是否可以从字符串创建比较运算符?

我正在尝试创建一个函数,该函数将从预定义的数组中生成 if 条件。


例如:


package errors


type errorCase struct {

    // This is the field I need to get in another struct

    Field        string

    // The comparison operator

    TestOperator string

    // The value that the expected one should not with equal...

    WrongValue   interface{}

}


var ErrorCases = []*errorCase{ {

    "MinValue",

    "<",

    0,

}, {

    "MaxValue",

    "==",

    0,

}}

实际上,我用 for 循环创建了一个新函数,该函数迭代所有这些“错误情况”


func isDirty(questionInterface models.QuestionInterface) bool {

    for _, errorCase := range errors.ErrorCases {

        s := reflect.ValueOf(&questionInterface).Elem()

        value := s.Elem().FieldByName(errorCase.Field)


        // At this point I need to create my if condition

        // to compare the value of the value var and the wrong one

        // With the given comparison operator

    }


    // Should return the comparison test value

    return true

}

是否可以创建这样的 if 条件?使用反射包?


我认为这是可能的,但我不知道应该从哪里开始。


隔江千里
浏览 73回答 1
1回答

jeck猫

这个有可能。我以前构建过一个像这样的通用比较库。简单来说,比较包含三个部分:某种值,位于比较的左侧。运算符(&nbsp;=,&nbsp;<,&nbsp;>, ...)。某种值,位于比较的右侧。这 3 个部分仅包含两种不同的类型 -&nbsp;value和operator。我试图将这两种类型抽象为它们的基本形式。value可以是任何东西,所以我们使用空接口 -&nbsp;interface{}。运算符是有限集的一部分,每个运算符都有自己的规则。type&nbsp;Operator&nbsp;int const&nbsp;( &nbsp;&nbsp;&nbsp;&nbsp;Equals&nbsp;Operator&nbsp;=&nbsp;1 &nbsp;&nbsp;&nbsp;&nbsp;)评估与符号的比较=只有一条有效规则 - 两个值应该属于同一类型。你无法比较1和hello。之后,您只需确保这些值相同即可。我们可以实现一个新的元类型来包装评估operator.评估与符号的比较=只有一条有效规则 - 两个值应该属于同一类型。你无法比较1和hello。之后,您只需确保这些值相同即可。我们可以实现一个新的元类型来包装评估operator.// Function signature for a "rule" of an operator.type validFn func(left, right interface{}) bool// Function signature for evaluating an operator comparison.type evalFn func(left, right interface{}) booltype operatorMeta struct {&nbsp; &nbsp; valid []validFn&nbsp; &nbsp; eval&nbsp; evalFn}现在我们已经定义了类型,我们需要实现 的规则和比较函数Equals。func sameTypes(left, right interface{}) bool {&nbsp; &nbsp; return reflect.TypeOf(left).Kind() == reflect.TypeOf(right).Kind()}func equals(left, right interface{}) bool {&nbsp; &nbsp; return reflect.DeepEqual(left, right)}惊人的!因此,我们现在可以验证两个值是否属于同一类型,如果是,我们可以将它们相互比较。难题的最后一部分是将运算符映射到其适当的规则和评估,并具有执行所有这些逻辑的函数。var args = map[Operator]operatorMeta{&nbsp; &nbsp; Equals: {&nbsp; &nbsp; &nbsp; &nbsp; valid: []validFn{sameTypes},&nbsp; &nbsp; &nbsp; &nbsp; eval:&nbsp; equals,&nbsp; &nbsp; },}func compare(o Operator, left, right interface{}) (bool, error) {&nbsp; &nbsp; opArgs, ok := args[o]&nbsp; &nbsp; if !ok {&nbsp; &nbsp; &nbsp; &nbsp; // You haven't implemented logic for this operator.&nbsp; &nbsp; }&nbsp; &nbsp; for _, validFn := range opArgs.valid {&nbsp; &nbsp; &nbsp; &nbsp; if !validFn(left, right) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // One of the rules were not satisfied.&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return opArgs.eval(left, right), nil}让我们总结一下到目前为止我们所得到的:将基本比较抽象为值和运算符。创建了一种方法来验证一对值对于运算符是否有效。创建了一种在给定两个值的情况下评估运算符的方法。(去游乐场)我希望我能对您如何解决这个问题提供一些见解。这是一个简单的想法,但需要一些样板才能正常工作。祝你好运!
打开App,查看更多内容
随时随地看视频慕课网APP