这是我的要求:我有两组常数。我想形成第三组,这只是上述两组的联合。我如何实现这一目标?
type CompOp byte
const (
EQUAL CompOp = iota
NOT_EQUAL
)
type LogOp byte
const (
AND LogOp = iota
OR
)
我想要第三套,比如说运营商
type Op {CompOp, LogOp}
或
var Op = CompOp + LogOp
但上述两种方式都不起作用。我如何达到这个要求?
以上对我来说很重要我试图实现这个目标:
type logExpr struct {
expr Expression
op LogOp
}
type compExpr struct {
expr Expression
op CompOp
}
type filterExpr struct {
expr Expression
op Op
}
答案 0 :(得分:6)
CompOp
和LogOp
不是同一类型的集合。它们不能以这种方式组合。如果他们可以,他们会发生冲突,因为EQUAL
和AND
都是0(因为他们是他们的块中的第一个iota
)。你需要另一种设计。
最常见的设计是将所有运算符合并到一个const
块中,然后提供IsCompare()
或IsLogic()
等函数,以便在必要时区分它们。请参阅os.IsExist()
和os.IsPermission()
作为模板。
这是我可以实现它的一种方式。它浪费了一些min / max值,但它使代码非常易于阅读并且易于更新。
const (
// Comparison operators
minComparison Op = iota
EQUAL
NOT_EQUAL
maxComparison
// Logic operators
minLogic
AND
OR
maxLogic
)
func IsComparsion(op Op) bool {
return op >= minComparison && op <= maxComparison
}
func IsLogic(op Op) bool {
return op >= minLogic && op <= maxLogic
}
但是你可以将不同类型的操作视为类型吗?是的,你可以,也许它对你来说会更好。例如,考虑(playground):
type Op interface {
isOp()
}
type CompOp byte
const (
EQUAL CompOp = iota
NOT_EQUAL
)
func (op CompOp) isOp() {}
type LogOp byte
const (
AND LogOp = iota
OR
)
func (op LogOp) isOp() {}
func doOpThingBasedOnValue(op Op) {
switch op {
case EQUAL:
println("passed equal")
case AND:
println("passed and")
}
}
func doOpThingBasedOnType(op Op) {
switch op.(type) {
case CompOp:
println("passed a comp")
case LogOp:
println("passed a logic")
}
}
所以也许这更接近你的想法。请注意,即使AND
和EQUAL
都是“0”,作为界面,它们也是可区分的,因此我们可以像您想要的那样打开它们。这样很酷。