为什么我可以输入别名函数并使用它们而不进行转换?(Why can I type alias functions and use them without casting?)

在Go中,如果您定义了新的类型,例如:

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 }

精细。 但是为什么同样的不适用于函数呢? 例如:

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转换为MyFunc类型,就像我在第一个例子中必须做的那样; 它似乎不一致。 我确定有一个很好的理由; 任何人都可以启发我吗?

我问的原因主要是因为我想以这种方式缩短一些我相当长的功能类型,但是我想确保这样做是可以接受的:

In Go, if you define a new type e.g.:

type MyInt int

You can't then pass a MyInt to a function expecting an int, or vice versa:

func test(i MyInt) { //do something with i } func main() { anInt := 0 test(anInt) //doesn't work, int is not of type MyInt }

Fine. But why is it then that the same does not apply to functions? e.g.:

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 }

Now, I'm not complaining because it saves me having to explicitly cast newfunc to type MyFunc, as I would have to do in the first example; it just seems inconsistent. I'm sure there is a good reason for it; can anyone enlighten me?

The reason I ask is mainly because I would like to shorten some of my rather long function types in this way, but I want to make sure it's expected and acceptable to do this :)

最满意答案

原来,这是一个误解,我已经谈到了如何处理类型,这可以通过阅读规范的相关部分来解决:

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)

我有点内疚,我早就不知道了,所以我希望能够为别人澄清一点点类型! 并且意味着比我想象的少得多的铸造:)

Turns out, this is a misunderstanding that I had about how Go dealt with types, which can be resolved by reading the relevant part of the spec:

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

The relevant distinction that I was unaware of was that of named and unnamed types.

Named types are types with a name, such as int, int64, float, string, bool. In addition, any type you create using 'type' is a named type.

Unnamed types are those such as []string, map[string]string, [4]int. They have no name, simply a description corresponding to how they are to be structured.

If you compare two named types, the names must match in order for them to be interchangeable. If you compare a named and an unnamed type, then as long as the underlying representation matches, you're good to go!

e.g. given the following types:

type MyInt int type MyMap map[int]int type MySlice []int type MyFunc func(int)

the following is invalid:

var i int = 2 var i2 MyInt = 4 i = i2 //both named (int and MyInt) and names don't match, so invalid

the following is fine:

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)

I'm a bit gutted I didn't know that sooner, so I hope that clarifies the type lark a little for someone else! And means much less casting than I at first thought :)

为什么我可以输入别名函数并使用它们而不进行转换?(Why can I type alias functions and use them without casting?)

在Go中,如果您定义了新的类型,例如:

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 }

精细。 但是为什么同样的不适用于函数呢? 例如:

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转换为MyFunc类型,就像我在第一个例子中必须做的那样; 它似乎不一致。 我确定有一个很好的理由; 任何人都可以启发我吗?

我问的原因主要是因为我想以这种方式缩短一些我相当长的功能类型,但是我想确保这样做是可以接受的:

In Go, if you define a new type e.g.:

type MyInt int

You can't then pass a MyInt to a function expecting an int, or vice versa:

func test(i MyInt) { //do something with i } func main() { anInt := 0 test(anInt) //doesn't work, int is not of type MyInt }

Fine. But why is it then that the same does not apply to functions? e.g.:

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 }

Now, I'm not complaining because it saves me having to explicitly cast newfunc to type MyFunc, as I would have to do in the first example; it just seems inconsistent. I'm sure there is a good reason for it; can anyone enlighten me?

The reason I ask is mainly because I would like to shorten some of my rather long function types in this way, but I want to make sure it's expected and acceptable to do this :)

最满意答案

原来,这是一个误解,我已经谈到了如何处理类型,这可以通过阅读规范的相关部分来解决:

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)

我有点内疚,我早就不知道了,所以我希望能够为别人澄清一点点类型! 并且意味着比我想象的少得多的铸造:)

Turns out, this is a misunderstanding that I had about how Go dealt with types, which can be resolved by reading the relevant part of the spec:

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

The relevant distinction that I was unaware of was that of named and unnamed types.

Named types are types with a name, such as int, int64, float, string, bool. In addition, any type you create using 'type' is a named type.

Unnamed types are those such as []string, map[string]string, [4]int. They have no name, simply a description corresponding to how they are to be structured.

If you compare two named types, the names must match in order for them to be interchangeable. If you compare a named and an unnamed type, then as long as the underlying representation matches, you're good to go!

e.g. given the following types:

type MyInt int type MyMap map[int]int type MySlice []int type MyFunc func(int)

the following is invalid:

var i int = 2 var i2 MyInt = 4 i = i2 //both named (int and MyInt) and names don't match, so invalid

the following is fine:

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)

I'm a bit gutted I didn't know that sooner, so I hope that clarifies the type lark a little for someone else! And means much less casting than I at first thought :)