1 回答
TA贡献1909条经验 获得超7个赞
这个有可能。我以前构建过一个像这样的通用比较库。
简单来说,比较包含三个部分:
某种值,位于比较的左侧。
运算符(
=
,<
,>
, ...)。某种值,位于比较的右侧。
这 3 个部分仅包含两种不同的类型 - value和operator。我试图将这两种类型抽象为它们的基本形式。
value可以是任何东西,所以我们使用空接口 -
interface{}
。运算符是有限集的一部分,每个运算符都有自己的规则。
type Operator int const ( Equals Operator = 1 )
评估与符号的比较=
只有一条有效规则 - 两个值应该属于同一类型。你无法比较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{}) bool
type operatorMeta struct {
valid []validFn
eval evalFn
}
现在我们已经定义了类型,我们需要实现 的规则和比较函数Equals。
func sameTypes(left, right interface{}) bool {
return reflect.TypeOf(left).Kind() == reflect.TypeOf(right).Kind()
}
func equals(left, right interface{}) bool {
return reflect.DeepEqual(left, right)
}
惊人的!因此,我们现在可以验证两个值是否属于同一类型,如果是,我们可以将它们相互比较。难题的最后一部分是将运算符映射到其适当的规则和评估,并具有执行所有这些逻辑的函数。
var args = map[Operator]operatorMeta{
Equals: {
valid: []validFn{sameTypes},
eval: equals,
},
}
func compare(o Operator, left, right interface{}) (bool, error) {
opArgs, ok := args[o]
if !ok {
// You haven't implemented logic for this operator.
}
for _, validFn := range opArgs.valid {
if !validFn(left, right) {
// One of the rules were not satisfied.
}
}
return opArgs.eval(left, right), nil
}
让我们总结一下到目前为止我们所得到的:
将基本比较抽象为值和运算符。
创建了一种方法来验证一对值对于运算符是否有效。
创建了一种在给定两个值的情况下评估运算符的方法。
我希望我能对您如何解决这个问题提供一些见解。这是一个简单的想法,但需要一些样板才能正常工作。
祝你好运!
- 1 回答
- 0 关注
- 126 浏览
添加回答
举报