英文:
Are typedefs for primitive values equivalent in golang?
问题
给定这段代码:
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
的结果。
为什么类型检查器没有报错呢?因为类型安全的枚举应该限制值的范围。
英文:
Given this code:
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"
}
Calling Quote(5)
will print Foo.Philosopher
as the type for 5.
Why didn't the type checker complain since that is what a type safe enums are supposed to do i.e. limit the scope of values ?
答案1
得分: 9
这些并不是你所认为的枚举类型。Philosopher
类型更多地是 int 的别名。更准确地说,它是一种基本不同的类型,可以定义自己的方法。
它的目的是以一种对程序员来说清晰明了的方式提供常量的语义分组。此外,在编译时,你可以享受到 Go 的类型检查器的好处。但是只有在将值传递给 func(Philosopher)
时,才能确保参数不能被隐式解释为其他类型。传递字面量 5
作为参数是可以的,因为在 Go 中这样的常量本质上是无类型的。但是下面的代码将无法通过编译:
n := 5
Quote(n) // 编译错误 -> int 不是 Philosopher
原因是 n
被定义为 int
类型。int
类型和 Philosopher
类型之间不存在隐式转换。然而,下面的代码可以通过编译:
n := 5
Quote(Philosopher(n))
因为类型转换是有效的。Go 不关心 5
是否是一个有效且预定义的 Philosopher
常量。
英文:
These are not enums as you think of them. Type Philosopher
is more or less an alias of an int. More or less, because it is a fundamentally distinct type, which can define its own methods.
The point of it is to provide semantic grouping of constants in a way that is clear to the programmer. Additionally, one gets the benefit of Go's type checker during compile time. But only to the degree that a value passed into a func(Philosopher)
can not be implicitly interpreted as such. Passing a literal 5
as the parameter works, because constants like that in Go are inherently untyped. This will not work;
n := 5
Quote(n) // Compile error -> int is not Philosopher
Reason being that n
is defined as int
. There exists no implicit conversion between type int
and Philosopher
. However, this will work:
n := 5
Quote(Philosopher(n))
Because the type cast is valid. Go does not care whether or not 5
is a valid and pre-defined Philosopher
constant.
答案2
得分: 1
Go对有效值没有任何保证,除了int所暗示的值。使用iota只是为了方便定义一系列常量;它并不表示任何关于有效值的信息。
5是一个有效的int,因此也是一个有效的Philosopher。你也可以创建const Plato = Philosopher(5)。
英文:
Go doesn’t make any guarantees about valid values, except for those implied by int. The use of iota is just a convenience for defining a series of constants; it doesn’t say anything about valid values.
5 is a valid int, and therefore a valid Philosopher. You could also create const Plato = Philosopher(5).
答案3
得分: 1
更简短的答案应该是:未类型化的常量会根据其上下文需要的类型进行推断。
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论