当我定义一个自定义类型时,基础类型的类型似乎对我是否可以按原样将其传递给函数还是需要对其进行转换有所不同。
问题是: 为什么RuneFunc和StringMap起作用,但不起作用Integer?
RuneFunc
StringMap
Integer
https://play.golang.org/p/buKNkrg5y-
package main type RuneFunc func(rune) rune type Integer int type StringMap map[string]string func main() { //m := make(StringMap) //mf(m) var i Integer = 5 nf(i) //var f func(rune) rune //ff(f) } func mf(i map[string]string) { } func ff(i func(rune)rune) { } func nf(i int) { }
在这里,当我运行此函数时nf,Integer它会抱怨,尽管它int是基础类型。但是当我打电话mf或ff他们成功运行时。
nf
int
mf
ff
int您的新类型Integer是2种不同的不同类型。在Integer预期的地方,您必须传递type的值Integer。
如果有Integer值,则可以使用简单的类型转换将其设为type的值int,因为的基础类型Integer为int:
var i Integer = 5 nf(int(i))
同时可能令人困惑和有趣的是,您可以不经过转换就传递未类型的常量:
nf(5)
在Go Playground上尝试一下。
原因是在规范中:可分配性:
在以下任何一种情况下,值x都可以 分配 给类型的变量T(“ x可以分配给T”): […] x是可由type值表示的无类型常量T。
在以下任何一种情况下,值x都可以 分配 给类型的变量T(“ x可以分配给T”):
x
T
[…]
5是一个无类型的常量,可以用type的值表示,int因为该无类型的常量5具有默认类型 int,所以它可以用type的值Integer(具有相同的默认类型)表示。
5
如果您检查其他可分配性规则(上面的报价中未包括),则它们都不与尝试为Integer类型的参数传递值的情况匹配int,因此不允许这样做。
请参阅相关问题:Golang:创建常量类型并限制类型的值
func(rune) rune
此案例与上一个案例(Integer和int)之间的区别在于,它int是命名类型,func(rune) rune不是。
有一个可分配性规则允许这样做:
* x的类型,V并且T具有相同的基础类型,并且至少是V或T不是命名类型。
V
因此,在这种情况下:
var f RuneFunc ff(f)
f是一个命名的类型,但是参数类型ff()就是func(rune) rune它是无名的,所以转让是允许的。
f
ff()