在 Go 中,如果你定义了一个新类型,例如:
type MyInt int
然后您不能将 a 传递给MyInt需要 int 的函数,反之亦然:
MyInt
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为 type MyFunc;这似乎不一致。我相信这是有充分理由的;任何人都可以启发我吗?
newfunc
MyFunc
我问的原因主要是因为我想以这种方式缩短一些相当长的函数类型,但我想确保这样做是预期和可接受的:)
事实证明,这是我对 Go 如何处理类型的误解,可以通过阅读规范的相关部分来解决:
http://golang.org/ref/spec#Type_identity
我不知道的相关区别是命名和未命名类型的区别。
命名类型是具有名称的类型,例如 int、int64、float、string、bool。此外,您使用“type”创建的任何类型都是命名类型。
未命名类型是诸如 []string、map[string]string、[4]int 之类的类型。它们没有名称,只是一个与它们的结构相对应的描述。
如果比较两个命名类型,名称必须匹配才能互换。如果您比较命名类型和未命名类型,那么只要底层表示匹配,您就可以开始了!
例如,给定以下类型:
type MyInt int type MyMap map[int]int type MySlice []int type MyFunc func(int)
以下是无效的:
var i int = 2 var i2 MyInt = 4 i = i2 //both named (int and MyInt) and names don't match, so invalid
以下是好的:
is := make([]int) m := make(map[int]int) f := func(i int){} //OK: comparing named and unnamed type, and underlying representation //is the same: func doSlice(input MySlice){...} doSlice(is) func doMap(input MyMap){...} doMap(m) func doFunc(input MyFunc){...} doFunc(f)
我有点内疚我不知道早点,所以我希望能澄清其他人的类型云雀!并且意味着比我最初想象的要少得多:)