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 關注
- 183 瀏覽
添加回答
舉報