为了账号安全,请及时绑定邮箱和手机立即绑定

切片与类型别名作为方法接收器

切片与类型别名作为方法接收器

Go
一只甜甜圈 2022-05-18 14:06:02
我有一个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()

这种转换不改变内存布局,只改变类型,因此安全高效。我们仅使用它来访问具有相同基础类型的类型的方法。


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号