为什么我可以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 }
- “int”和“uint”/“long”和“ulong”有什么区别?
- jQuery的 – 如何使$ .post()使用contentType =应用程序/ json?
- 为什么在C ++中,我们使用DWORD而不是unsigned int?
- 将int的stream转换为java中的char
- C#'unsafe'函数 – *(float *)(&result)vs(float)(result)
- id是什么意思?
- 学习scala的小型和好的scala项目 – 尤其是函数式编程和types系统
- JAXB:如何在XSD中指定attrtypes时更改XJC生成的类名称?
- 是什么让Haskell的types系统比其他语言的types系统更“强大”呢?