3 回答
TA贡献1843条经验 获得超7个赞
假设T是struct,那么Go里面遵循下面几个原则:
T的方法集仅拥有 T Receiver 方法。
*T 方法集则包含全部方法 (T + *T)。
所以你上面的例子dept1应该是拥有方法:Name和SetName
而&dept1拥有方法:Name、SetName和Relocate
这个就是Go里面在设计方法的时候需要注意Receiver的类型
TA贡献1856条经验 获得超5个赞
1、结构Dept
的方法集中仅包含方法接收者为Dept的方法,即:Name()
和SetName()
)。所以,结构Dept的实例仅为DeptModeA
的实现。
2、结构的指针*Dept
的方法集包含了方法接受者为Dept
和*Dept
的方法,即:Name()
、SetName()
和Relocate()
。所以,接口Dept的实例的指针为全部三个接口——DeptModeFull
、DeptModeA
和DeptModeB
的实现。
但是我觉得上述设计和原则与方法调用的设计有些不一致,请看下面的代码:
dept1.Relocate("Media", 12)fmt.Printf("Dept: %v\n", dept1)fmt.Printf("Dept name: %v\n", deptPtr1.Name())
打印的内容:
Dept: {MySohu Media 12 } Dept name: MySohu
这说明:结构Dept
的实例可以调用其指针方法集中的方法。
我觉得设计不一致的地方是:既然结构的访法集不包含接收者为其指针的方法,那又为什么让在结构的实例上可以调用其指针访法集中的方法呢?反过来看,既然结构的实例可以调用其接口访法集上的方法,那为什么不让结构的方法集直接包含这些方法呢?
不过,不管怎样,这引出了第三条规则(官方规范的意译):
3、如果结构的实例x
是“可被寻址的”,且&x
的方法集中包含方法m
,则x.m()
为(&x).m()
的速记(快捷方式)。
TA贡献1841条经验 获得超3个赞
所以其实
dept1.Relocate("Media", 12)
被自动转化成了?
(&dept1).Relocate("Media", 12)
学习了。
可寻址的意思大概就是已经实例话了。如果你直接
var deptPtr2 *Dept deptPtr2.Relocate("Media", 12)
就不行。反之:
var deptPtr2 Dept deptPtr2.Relocate("Media", 12)
就可以。区别就在这里了。
- 3 回答
- 0 关注
- 137 浏览
添加回答
举报