在Golang中扩展常量

时间:2015-08-17 12:22:29

标签: go constants

这是我的要求:我有两组常数。我想形成第三组,这只是上述两组的联合。我如何实现这一目标?

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 
}

1 个答案:

答案 0 :(得分:6)

CompOpLogOp不是同一类型的集合。它们不能以这种方式组合。如果他们可以,他们会发生冲突,因为EQUALAND都是0(因为他们是他们的块中的第一个iota)。你需要另一种设计。

最常见的设计是将所有运算符合并到一个const块中,然后提供IsCompare()IsLogic()等函数,以便在必要时区分它们。请参阅os.IsExist()os.IsPermission()作为模板。

这是我可以实现它的一种方式。它浪费了一些min / max值,但它使代码非常易于阅读并且易于更新。

Playground

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")
    }
}

所以也许这更接近你的想法。请注意,即使ANDEQUAL都是“0”,作为界面,它们也是可区分的,因此我们可以像您想要的那样打开它们。这样很酷。