gpt4 book ai didi

go - 在 Go 中,有什么方法可以比较两个没有嵌套 switch 语句的混合类型接口(interface)?

转载 作者:IT王子 更新时间:2023-10-29 02:23:43 25 4
gpt4 key购买 nike

我发现,Go 的 interface{} 类型是该语言最好的也是最烦人的特性。我正在尝试创建一个简单的用户可自定义的验证规则解决方案,用户可以在其中定义:

  • 比较运算符。
  • 比较操作数。
  • 指向要测试的值的映射键。

还有一个简单的 bool 表达式解析器,允许用户使用 AND 和 OR 组合多个规则。到目前为止一切正常,表达式可以被成功解析、标记化和评估,但它在给定数据上运行规则会导致问题。

这是实际评估数据的函数的当前版本:

/*
validate returns a boolean value denoting whether a test was successful. This
function will panic if the type assertions fail.
*/
func (sfvre standardFieldValidationRuleEntry) validate(fieldValue interface{}) bool {

switch sfvre.Operator() {
case VROP_EQUAL:
return fieldValue == sfvre.ComparisonOperand()
case VROP_NEQUAL:
return fieldValue != sfvre.ComparisonOperand()
case VROP_GT:
return fieldValue.(int) > sfvre.ComparisonOperand().(int)
case VROP_LT:
return fieldValue.(int) < sfvre.ComparisonOperand().(int)
case VROP_GTET:
return fieldValue.(int) >= sfvre.ComparisonOperand().(int)
case VROP_LTET:
return fieldValue.(int) <= sfvre.ComparisonOperand().(int)
case VROP_CONTAINS:
return strings.Contains(fieldValue.(string), sfvre.ComparisonOperand().(string))
case VROP_NCONTAINS:
return !strings.Contains(fieldValue.(string), sfvre.ComparisonOperand().(string))
default:
return false
}
}

目前,运算符暗示数据是否为数字(大于、小于等)。对 int 的类型断言在构建包的其他部分时完成了这项工作,但完成的系统也应该能够采用 float64 并能够处理混合类型比较。

目前我能看到的唯一方法是使用多个嵌套类型开关,每个开关一个级别:

  • 运营商。
  • 给定字段值的类型。
  • 比较操作数的类型。

但这有可能变得非常大且不易管理。是否有一种我看不到的“更干净”的方法来执行此操作,或者我是否一直在使用嵌套开关?

最佳答案

我现在得到的解决方案(感谢@Volker 的建议)对需要比较的值进行了快速类型切换,而不是使用 Operator() 中的原始值> 开关,它使用具体的浮点值:

/*
validate returns a boolean value denoting whether a test was successful. This
function will panic if the type assertions fail.
*/
func (sfvre standardFieldValidationRuleEntry) validate(fieldValue interface{}) bool {

var floatFieldVal, floatCompVal float64

//If the interface is int or float, convert it to a statically typed float64.
switch fieldValue.(type) {
case int:
floatFieldVal = float64(fieldValue.(int))
case float64:
floatFieldVal = fieldValue.(float64)
}

//Do the same with the comparison value.
switch sfvre.ComparisonOperand().(type) {
case int:
floatCompVal = float64(sfvre.ComparisonOperand().(int))
case float64:
floatCompVal = sfvre.ComparisonOperand().(float64)
}

switch sfvre.Operator() {
case VROP_EQUAL:
return fieldValue == sfvre.ComparisonOperand()
case VROP_NEQUAL:
return fieldValue != sfvre.ComparisonOperand()
case VROP_GT:
return floatFieldVal > floatCompVal
case VROP_LT:
return floatFieldVal < floatCompVal
case VROP_GTET:
return floatFieldVal >= floatCompVal
case VROP_LTET:
return floatFieldVal <= floatCompVal
case VROP_CONTAINS:
return strings.Contains(fieldValue.(string), sfvre.ComparisonOperand().(string))
case VROP_NCONTAINS:
return !strings.Contains(fieldValue.(string), sfvre.ComparisonOperand().(string))
default:
return false
}
}

它并不能捕获所有内容,但是根据用户正在比较的字段限制用户可以选择的运算符可以缓解这种情况,但这是更大的解决方案的一部分,因此在这里无关紧要。

关于go - 在 Go 中,有什么方法可以比较两个没有嵌套 switch 语句的混合类型接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33258026/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com