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