我有一个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 codefunc (fs []Foo) print() { for _, f := range fs { f.print() }}上述方法不起作用,因为在 Go 中,不能将未命名类型用作方法接收器,如此 Google Group thread中所述。为了规避它,可以写:type Foos []Foofunc (fs Foos) print() { for _, f := range fs { f.print() }}要使用它,我必须将类型显式声明为Foos,所以我仍然不能使用printon[]Foofs := []Foo{}fs.print() // errorvar fss Foos = fsfss.print()我感到困惑的是,在上面的代码中,fss并且fs显然属于同一类型,因为我可以毫无错误地分配fs给它fss。但是,我们不能简单地使用fs.print()Go 并让 Go 智能转换。为什么会这样?
1 回答
四季花海
TA贡献1811条经验 获得超5个赞
我感到困惑的是,在上面的代码中,
fss并且fs显然属于同一类型,因为我可以毫无错误地分配fs给它fss。
你跳到错误的结论。具有相同的类型并不是可分配性的必须要求。
fss有 type Foos,并且fs有 type []Foo,一个未命名的切片类型。确实,它们具有相同的基础类型,这就是您可以分配fs到的原因fss,这在此可分配性规则中有所涵盖:
如果以下条件之一适用,则值
x可分配给类型的变量T(“x可分配给”):T
方法绑定到具体类型。因此,该Foos.print()方法不适用于其他类型的值,包括[]Foo.
但是您不需要创建变量来调用该方法,您可以简单地使用类型转换:
Foos(fs).print()
这种转换不改变内存布局,只改变类型,因此安全高效。我们仅使用它来访问具有相同基础类型的类型的方法。
- 1 回答
- 0 关注
- 152 浏览
添加回答
举报
0/150
提交
取消
