为什么我可以input别名函数并使用它们而不需要强制转换?

在Go中,如果你定义了一个新types,例如:

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 } 

精细。 但是,为什么同样不适用于function呢? 例如:

 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我不得不明确地投入newfunc键入MyFunc ,因为我必须在第一个例子中做; 这似乎不一致。 我确信有一个很好的理由。 谁能开导我?

我问的原因主要是因为我想通过这种方式缩短一些我相当长的函数types,但我想确保它是预期的和可以接受的做到这一点:)

原来,这是我对Go处理types的误解,可以通过阅读规范的相关部分来解决:

http://golang.org/ref/spec#Type_identity

我不知道的相关区别是命名未命名的types。

命名types是具有名称的types,例如int,int64,float,string,bool。 另外,使用'type'创build的任何types都是一个命名types。

未命名的types是那些诸如[] string,map [string] string,[4] int。 他们没有名字,只是一个对应于他们如何构build的描述。

如果您比较两个命名types,名称必须匹配以便它们可以互换。 如果你比较一个已命名和未命名的types,那么只要潜在的表示匹配 ,你就可以走了!

例如给出以下types:

 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) 

我有点内脏,我不知道早点,所以我希望能澄清一下其他人的types。 而且意味着比起初我想的要less得多:)

问题和答案都很有启发性。 但是,我想提出一个在lytnus的答案中不明确的区分。

  • 命名types不同于无名types

  • 命名types的variables可以分配给未命名types的variables,反之亦然。

  • 不同命名types的variables不能相互赋值。

http://play.golang.org/p/uaYHEnofT9

 import ( "fmt" "reflect" ) type T1 []string type T2 []string func main() { foo0 := []string{} foo1 := T1{} foo2 := T2{} fmt.Println(reflect.TypeOf(foo0)) fmt.Println(reflect.TypeOf(foo1)) fmt.Println(reflect.TypeOf(foo2)) // Output: // []string // main.T1 // main.T2 // foo0 can be assigned to foo1, vice versa foo1 = foo0 foo0 = foo1 // foo2 cannot be assigned to foo1 // prog.go:28: cannot use foo2 (type T2) as type T1 in assignment // foo1 = foo2 }