2 回答

TA貢獻(xiàn)1891條經(jīng)驗(yàn) 獲得超3個(gè)贊
使用方法允許您定義接口。假設(shè)你有:
func (m *ProbeManager) Run(w *ProbeWorker) {}
您可以創(chuàng)建一個(gè)接口:
type Manager interface {
Run(w *ProbeWorker)
}
現(xiàn)在任何需要的東西都*ProbeManager可以Manager代替。這Run與其實(shí)現(xiàn)的細(xì)節(jié)脫鉤。這很有用的原因有很多:
它使代碼更容易推理并且更容易安全地更改,因?yàn)樗[藏了不必要的細(xì)節(jié)(信息隱藏)
它使代碼更易于測(cè)試,因?yàn)槟梢阅M接口并單獨(dú)測(cè)試一小段代碼:
type mockManager struct {
run func(w *ProbeWorker)
}
func (m mockManager) Run(w *ProbeWorker) {
m.run(w)
}
func Test(t *testing.T) {
wasCalled := false
m := mockManager{
run: func(w *ProbeWorker) {
wasCalled = true
},
}
// pass m to something that takes a Manager
}
接口還使您能夠?qū)崿F(xiàn)依賴注入。有很多方法,但一個(gè)非常簡(jiǎn)單的方法是提供一個(gè)Default實(shí)現(xiàn):
var DefaultManager Manager = &ProbeManager{}
或者基于字符串的注冊(cè)表:
var managerLookup = map[string]Manager{}
func RegisterManager(nm string, m Manager) {
managerLookup[nm] = m
}
func GetManager(nm string) Manager {
return managerLookup[nm]
}
這非常強(qiáng)大,因?yàn)樗试S您修改現(xiàn)有包的行為而無(wú)需更改其代碼。(例如,假設(shè)您有一個(gè)文件下載器并且您實(shí)現(xiàn)了http支持。其他人可以提供ftp支持,并且解析 URL 所需的代碼不需要通過(guò)使用此注冊(cè)表方法進(jìn)行更改)
接口允許您實(shí)現(xiàn)類(lèi)似的方法來(lái)解決您會(huì)在其他編程語(yǔ)言中發(fā)現(xiàn)的問(wèn)題。它們?yōu)槟峁┝艘环N通用的多態(tài)性(請(qǐng)參閱sort包),您可以通過(guò)實(shí)現(xiàn)調(diào)用相同接口的接口來(lái)實(shí)現(xiàn)面向方面的編程或猴子修補(bǔ)(考慮gzip.Reader調(diào)用底層File. 的任何東西,io.Reader也可以采用 a gzip.Reader,允許您無(wú)需更改其余代碼即可替換行為)
我可以繼續(xù)...

TA貢獻(xiàn)1815條經(jīng)驗(yàn) 獲得超13個(gè)贊
它們實(shí)際上都是等價(jià)的。接收者像其他所有參數(shù)一樣被傳遞到方法中。由于無(wú)論什么(調(diào)用方法)都需要手頭的兩種類(lèi)型,因此定義它并不重要。就個(gè)人而言,基于此,我將使用您的三個(gè)選項(xiàng)中的最后一個(gè)。這對(duì)我來(lái)說(shuō)更有意義,因?yàn)樵谄渌闆r下,您將方法與這兩種類(lèi)型之一相關(guān)聯(lián),而實(shí)際上它同時(shí)需要這兩種類(lèi)型。不過(guò),這只是您希望如何組織代碼的問(wèn)題。在性能或應(yīng)用程序行為方面,兩者之間沒(méi)有任何好處,它們都是一樣的。
編輯:最后一點(diǎn)。這些都不會(huì)被導(dǎo)出,所以它是一個(gè)“私有”或者更確切地說(shuō)是一種用作包內(nèi)部助手的方法。沒(méi)有接收類(lèi)型的更多理由。
- 2 回答
- 0 關(guān)注
- 161 瀏覽
添加回答
舉報(bào)