gpt4 book ai didi

go - slice 与类型别名作为方法接收器

转载 作者:行者123 更新时间:2023-12-01 20:23:21 25 4
gpt4 key购买 nike

我有一个结构 Foo用方法print :

type Foo struct {
Bar string
}
func (f Foo) print() {
fmt.Println(f.Bar)
}

如果我想打印 Foo 的一部分,规范的方法也许是写一个 for循环,并有一个函数来封装它:

func printFoos(fs []Foo) {
for _, f := range fs {
f.print()
}
}
printFoos([]Foo{})

来自 OOP 背景,我觉得这种方法有点不吸引人。

我想做的是关联 printFoos[]Foo :

// Invalid Go code
func (fs []Foo) print() {
for _, f := range fs {
f.print()
}
}

上述方法不起作用,因为在 Go 中,不能将未命名类型用作方法接收器,如 this Google Group thread 中所述。 .

为了规避它,可以写:

type Foos []Foo
func (fs Foos) print() {
for _, f := range fs {
f.print()
}
}

要使用它,我必须将类型显式声明为 Foos ,所以我还是不能使用 print[]Foo
fs := []Foo{}
fs.print() // error
var fss Foos = fs
fss.print()

我感到困惑的是,在上面的代码中, fssfs显然属于同一类型,我可以指定 fsfss没有错误。但是,我们不能简单地使用 fs.print()让 Go 在转换方面变得聪明。

为什么会这样?

完整代码见 playground .

最佳答案

What I'm confused about is, in the above code, fss and fs are clearly of the same type, as I can assign fs to fss without error.


你跳到错误的结论。具有相同类型不是 assignability 的必备要求. fss有类型 Foos , 和 fs有类型 []Foo ,一个未命名的 slice 类型。确实它们具有相同的底层类型,这就是为什么您可以分配 fsfss ,涵盖在此可分配性规则中:

A value x is assignable to a variable of type T ("x is assignable to T") if one of the following conditions applies:


方法绑定(bind)到具体类型。所以 Foos.print()方法不适用于不同类型的值,包括 []Foo .
但是你不需要创建一个变量来调用那个方法,你可以简单地使用一个类型 conversion :
Foos(fs).print()
这种转换不改变内存布局,只改变类型,因此安全高效。我们仅使用它来访问具有相同基础类型的类型的方法。

关于go - slice 与类型别名作为方法接收器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60316050/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com