为什么我可以键入别名函数并在不强制转换的情况下使用它们? [英] Why can I type alias functions and use them without casting?
问题描述
在 Go 中,如果你定义了一个新类型,例如:
In Go, if you define a new type e.g.:
type MyInt int
然后您不能将 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
}
现在,我没有抱怨,因为这样我就不必像在第一个示例中那样显式地强制转换 newfunc
以键入 MyFunc
;这似乎不一致.我相信这是有充分理由的;谁能给我指点一下?
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 :)
推荐答案
原来,这是我对 Go 如何处理类型的误解,可以通过阅读规范的相关部分来解决:
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
我不知道的相关区别是 named 和 unnamed 类型.
The relevant distinction that I was unaware of was that of named and unnamed types.
Named 类型是具有名称的类型,例如 int、int64、float、string、bool.此外,您使用type"创建的任何类型都是命名类型.
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 类型是诸如 []string、map[string]string、[4]int 之类的类型.它们没有名称,只是一个与它们的结构相对应的描述.
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!
例如给定以下类型:
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)
我有点内疚,我不知道早点知道,所以我希望能够为其他人澄清一下云雀的类型!并且意味着比我最初想象的要少得多:)
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 :)
这篇关于为什么我可以键入别名函数并在不强制转换的情况下使用它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!