在 Go 中,如果你定义了一个新类型,例如:
type MyInt int
然后,您不能将 MyInt
传递给需要 int 的函数,反之亦然:
func test(i MyInt) {
//do something with i
}
func main() {
anInt := 0
test(anInt) //doesn't work, int is not of type MyInt
}
美好的。但为什么同样不适用于函数呢?例如:
type MyFunc func(i int)
func (m MyFunc) Run(i int) {
m(i)
}
func run(f MyFunc, i int) {
f.Run(i)
}
func main() {
var newfunc func(int) //explicit declaration
newfunc = func(i int) {
fmt.Println(i)
}
run(newfunc, 10) //works just fine, even though types seem to differ
}
现在,我没有抱怨,因为它使我不必显式 newfunc
来键入 MyFunc
,就像我在第一个示例中必须做的那样;这似乎不一致。我敢肯定这是有充分理由的;谁能启发我?
我问的原因主要是因为我想以这种方式缩短一些相当长的函数类型,但我想确保这样做是预期的并且可以接受的:)
原文由 jsdw 发布,翻译遵循 CC BY-SA 4.0 许可协议
事实证明,这是我对 Go 如何处理类型的误解,可以通过阅读规范的相关部分来解决:
http://golang.org/ref/spec#Type_identity
我没有意识到的相关区别是 命名 类型和 未命名 类型的区别。
命名 类型是具有名称的类型,例如 int、int64、float、string、bool。此外,您使用“类型”创建的任何类型都是命名类型。
未命名 类型是 []string、map[string]string、[4]int 等类型。它们没有名称,只是与它们的结构相对应的描述。
如果比较两个命名类型,名称必须匹配才能互换。如果您比较命名类型和未命名类型,那么 只要底层表示匹配,您就可以开始了!
例如给定以下类型:
以下是无效的:
以下是好的:
我有点内疚,我没有早点知道,所以我希望这能为其他人稍微澄清一下百灵鸟的类型!并且意味着比我最初想象的要少得多:)