在Go中,有没有办法比较两个没有嵌套switch语句的混合类型接口?
我发现Go的在Go中,有没有办法比较两个没有嵌套switch语句的混合类型接口?,go,interface,type-switch,Go,Interface,Type Switch,我发现Go的接口{}类型是该语言最好的也是最烦人的特性。我正在尝试创建一个简单的用户可自定义验证规则解决方案,用户可以在其中定义: 比较运算符 比较操作数 指向要测试的值的映射键 以及一个简单的布尔表达式解析器,允许用户使用AND和OR组合多个规则。到目前为止,一切都很好,可以成功地解析、标记和计算表达式,但对给定数据运行规则会导致问题 这是实际评估数据的函数的当前版本: /* validate returns a boolean value denoting whether a test
接口{}
类型是该语言最好的也是最烦人的特性。我正在尝试创建一个简单的用户可自定义验证规则解决方案,用户可以在其中定义:
- 比较运算符
- 比较操作数
- 指向要测试的值的映射键
/*
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
}
}
/*
validate返回一个布尔值,指示测试是否成功。这
如果类型断言失败,函数将死机。
*/
func(sfvre standardFieldValidationRuleEntry)validate(fieldValue接口{})bool{
开关sfvre.Operator(){
案例VROP_等于:
返回字段值==sfvre.ComparisonOperand()
案例VROP_NEQUAL:
返回字段值!=sfvre.ComparisonOperand()
案例VROP\u GT:
返回字段值。(int)>sfvre.ComparisonOperand()(int)
案例VROP_LT:
返回字段值。(int)=sfvre.ComparisonOperand()(int)
案例VROP\U LTET:
return fieldValue.(int)我现在得到的解决方案(感谢@Volker的建议)对需要比较的值进行快速类型切换,然后使用具体的浮点值,而不是在操作符()中使用原始值
/*
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
}
}
/*
validate返回一个布尔值,指示测试是否成功
如果类型断言失败,函数将死机。
*/
func(sfvre standardFieldValidationRuleEntry)validate(fieldValue接口{})bool{
变量floatFieldVal,floatCompVal float64
//如果接口是int或float,请将其转换为静态类型的float64。
开关字段值。(类型){
案例int:
floatFieldVal=float64(fieldValue.(int))
案例64:
floatFieldVal=fieldValue。(float64)
}
//对比较值执行相同的操作。
开关sfvre.ComparisonOperand()(类型){
案例int:
floatCompVal=float64(sfvre.ComparisonOperand()(int))
案例64:
floatCompVal=sfvre.ComparisonOperand()(float64)
}
开关sfvre.Operator(){
案例VROP_等于:
返回字段值==sfvre.ComparisonOperand()
案例VROP_NEQUAL:
返回字段值!=sfvre.ComparisonOperand()
案例VROP\u GT:
返回floatFieldVal>floatCompVal
案例VROP_LT:
返回floatFieldVal=floatCompVal
案例VROP\U LTET:
return floatFieldVal我现在得到的解决方案(感谢@Volker的建议)对需要比较的值进行快速类型切换,然后使用具体的浮点值,而不是在操作符()中使用原始值
/*
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
}
}
/*
validate返回一个布尔值,指示测试是否成功
如果类型断言失败,函数将死机。
*/
func(sfvre standardFieldValidationRuleEntry)validate(fieldValue接口{})bool{
变量floatFieldVal,floatCompVal float64
//如果接口是int或float,请将其转换为静态类型的float64。
开关字段值。(类型){
案例int:
floatFieldVal=float64(fieldValue.(int))
案例64:
floatFieldVal=fieldValue。(float64)
}
//对比较值执行相同的操作。
开关sfvre.ComparisonOperand()(类型){
案例int:
floatCompVal=float64(sfvre.ComparisonOperand()(int))
案例64:
floatCompVal=sfvre.ComparisonOperand()(float64)
}
开关sfvre.Operator(){
案例VROP_等于:
返回字段值==sfvre.ComparisonOperand()
案例VROP_NEQUAL:
返回字段值!=sfvre.ComparisonOperand()
案例VROP\u GT:
返回floatFieldVal>floatCompVal
案例VROP_LT:
返回floatFieldVal=floatCompVal
案例VROP\U LTET:
返回一个更干净的方法如何工作?考虑一下<代码> IT64 64/代码>和<代码> UTIN 64 < /代码>。这样的比较必须处理很多情况,例如UT64值不能由因特64表示,反之亦然。这种情况取决于这两种类型,比较UTIT32到Field128有不同的规则。运算符您必须处理n*(n-1)*m/2个
案例(如果我计算正确的话)。并且没有捷径。或者您将任何输入限制为可由float64表示的内容,然后首先将任何内容转换为float64(可能单独处理字符串)。我希望对Go更了解的人能够向我透露:(我可能最终会将所有内容转换为float64。您是否可以将所有作为浮点输入的数字都转换为float64?Int->float会以一种不适合比较的方式丢失精度,因此您的混合类型比较将是Int到float,也可以在任何比较逻辑之前将所有内容转换/转换为float64。@evanmcdonnal se)e我的回答:)在进行任何比较之前(假设是数字),我已经将接口值放入具体类型中。恐怕我对浮点的知识还存在差距,但我的印象是,当您尝试将大浮点添加到小浮点时,您只会得到舍入错误/不准确(所以在添加之前一定要对术语进行排序)?@leylandski floats在精度上会有一些小错误,但直到idk小数点后10-20位才开始。我只是想说明一点,如果你给我一个int和一个float,并想要比较它们,就有n个