在golang中,原始值的typedef是否等效?

时间:2014-03-17 21:11:40

标签: go

鉴于此代码:

type Philosopher int
const (
    Epictetus Philosopher = iota
    Seneca
)

func Quote(who Philosopher) string {
    fmt.Println("t: ", reflect.TypeOf(who))
    switch who {
    case Epictetus:
        return "First say to yourself what you would be; 
                and do what you have to do"
    case Seneca:
        return "If a man knows not to which port he sails, 
                No wind is favorable"
    }
    return "nothing"
}

调用Quote(5)将打印Foo.Philosopher作为5的类型。 为什么类型检查器没有抱怨,因为类型安全枚举应该做什么,即限制值的范围?

3 个答案:

答案 0 :(得分:8)

这些不是你想到的枚举。类型Philosopher或多或少是int的别名。或多或少,因为它是一个基本上不同的类型,可以定义自己的方法。

重点是以程序员清楚的方式提供常量的语义分组。另外,在编译期间可以获得Go的类型检查器的好处。但仅限于传递给func(Philosopher)的值不能被隐含地解释为这样的程度。传递文字5作为参数有效,因为Go中的常量本身就是无类型的。这不起作用;

n := 5
Quote(n)  // Compile error -> int is not Philosopher

原因是n被定义为int。类型intPhilosopher之间不存在隐式转换。但是,这将有效:

n := 5
Quote(Philosopher(n))

因为类型转换有效。 Go不关心5是否是有效且预定义的Philosopher常量。

答案 1 :(得分:1)

Go不对有效值做任何保证,除了int隐含的那些值。使用iota只是定义一系列常量的便利;它没有说有效值。

5是一个有效的int,因此是一个有效的哲学家。你也可以创建const Plato = Philosopher(5)。

答案 2 :(得分:1)

更短的答案应该是{{3}}:

  

无类型的常量采用其上下文所需的类型。