鉴于此代码:
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的类型。
为什么类型检查器没有抱怨,因为类型安全枚举应该做什么,即限制值的范围?
答案 0 :(得分:8)
这些不是你想到的枚举。类型Philosopher
或多或少是int的别名。或多或少,因为它是一个基本上不同的类型,可以定义自己的方法。
重点是以程序员清楚的方式提供常量的语义分组。另外,在编译期间可以获得Go的类型检查器的好处。但仅限于传递给func(Philosopher)
的值不能被隐含地解释为这样的程度。传递文字5
作为参数有效,因为Go中的常量本身就是无类型的。这不起作用;
n := 5
Quote(n) // Compile error -> int is not Philosopher
原因是n
被定义为int
。类型int
和Philosopher
之间不存在隐式转换。但是,这将有效:
n := 5
Quote(Philosopher(n))
因为类型转换有效。 Go不关心5
是否是有效且预定义的Philosopher
常量。
答案 1 :(得分:1)
Go不对有效值做任何保证,除了int隐含的那些值。使用iota只是定义一系列常量的便利;它没有说有效值。
5是一个有效的int,因此是一个有效的哲学家。你也可以创建const Plato = Philosopher(5)。
答案 2 :(得分:1)
更短的答案应该是{{3}}:
无类型的常量采用其上下文所需的类型。