在Go中,有没有办法比较两个没有嵌套switch语句的混合类型接口?

在Go中,有没有办法比较两个没有嵌套switch语句的混合类型接口?,go,interface,type-switch,Go,Interface,Type Switch,我发现Go的接口{}类型是该语言最好的也是最烦人的特性。我正在尝试创建一个简单的用户可自定义验证规则解决方案,用户可以在其中定义: 比较运算符 比较操作数 指向要测试的值的映射键 以及一个简单的布尔表达式解析器,允许用户使用AND和OR组合多个规则。到目前为止,一切都很好,可以成功地解析、标记和计算表达式,但对给定数据运行规则会导致问题 这是实际评估数据的函数的当前版本: /* validate returns a boolean value denoting whether a test

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

  • 比较运算符
  • 比较操作数
  • 指向要测试的值的映射键
以及一个简单的布尔表达式解析器,允许用户使用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
    }
}
/*
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个