传递的自定义类型用作参数

Hor*_*ing 9 types type-conversion go

当我定义一个自定义类型时,似乎底层类型的类型对我是否可以将其传递给函数或我需要转换它有所不同.

问题是: 为什么RuneFuncStringMap有效,但不是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) {

}
Run Code Online (Sandbox Code Playgroud)

在这里,当我运行这个函数调用nfInteger它抱怨,虽然int是基础类型.但是当我打电话mfff他们成功运行时.

icz*_*cza 16

Integerint

int你的新类型Integer是2种不同的不同类型.在Integer预期的位置,您必须传递类型的值Integer.

如果您有Integer值,则可以使用简单类型转换使其成为类型的值int,因为基础类型Integerint:

var i Integer = 5
nf(int(i))
Run Code Online (Sandbox Code Playgroud)

同时令人困惑和有趣的是,您可以在不转换的情况下传递无类型常量:

nf(5)
Run Code Online (Sandbox Code Playgroud)

Go Playground尝试这些.

原因在于Spec:Assignability:

的值x分配可变型的T(" x是分配给T")在任何这些情况中:

[...]

  • x是一个无类型的常量,可以用类型的表示T.

5是一个无类型的常量,可以通过类型的值表示,int因为无类型的常量5具有默认类型 int,因此它可以通过类型的值Integer(具有相同的默认类型)来表示.

如果检查其他可分配性规则(未包括在上面的引号中),则它们都不匹配您尝试为Integer类型参数传递值的情况int,因此不允许这样做.

请参阅相关问题:Golang:创建常量类型并限制类型的值

RuneFuncfunc(rune) rune

这种情况与前一种情况(Integerint)之间的区别在于它int是一种命名类型func(rune) rune不是.

并且有一个可赋值规则允许这样:

所以在这种情况下:

var f RuneFunc
ff(f)
Run Code Online (Sandbox Code Playgroud)

f是一个命名的类型,但是参数类型ff()就是func(rune) rune它是无名的,所以转让是允许的.

  • 有趣!我从未注意到那条规则或它之前的真正含义. (3认同)