3 回答

TA貢獻1851條經驗 獲得超3個贊
正如已經提到的,返回一個接口應該被認為是特殊的事情。
返回接口類型的錯誤error就是其中之一。
返回表示未導出類型的接口是另一個例外。但是為什么要有一個描述未導出結構的導出接口,而不是僅僅有一個導出結構呢?
原因很簡單,這允許您更好地控制該結構的構造方式。
比較這兩段代碼:
type MyType struct {
MyField string
}
func NewMyType(value string) MyType {
return MyType{value}
}
func (t MyType) MyMethod() string {
return t.MyField
}
type MyType interface {
MyMethod() string
}
type myType struct {
MyField string
}
func NewMyType(value string) MyType {
return myType{value}
}
func (t myType) MyMethod() string {
return t.MyField
}
在第一種情況下,我可以這樣做:myVar := MyType{}而在第二種情況下,我將無法這樣做,我被迫使用提供的構造函數。第一種情況還允許在創建后修改字段值,而第二種情況則不允許。使該字段不導出將解決第二部分,但不能解決第一部分。
這個例子顯然是微不足道的,但是能夠構造無效的結構可能會產生可怕的影響。通過使用特定的構造函數,您可以確保對象處于有效的起始狀態,并且您只需要確保它始終保持有效狀態。如果您不能確保這一點,您可能需要在每個方法開始時檢查它是否處于有效狀態。
例如,考慮一個數據庫請求。它需要數據庫連接。如果用戶能夠在沒有數據庫連接的情況下創建數據庫請求,您將必須檢查它在每種方法中是否有效。如果你強迫他使用構造函數,你可以在創建時檢查并完成。

TA貢獻1828條經驗 獲得超6個贊
這在一定程度上取決于您的偏好以及您如何看待事物。來自 OOP 背景的我的看法是:如果不能強制執行構造函數,那么構造函數就沒有任何意義。添加構造函數意味著 - 您必須在實例化此項時提供這些值。如果您的結構是公共的,它將被濫用并繞過構造函數進行實例化。因此,構造函數返回公共接口并且結構是私有的(小寫)是有意義的。如果結構是公共的,則構造函數中沒有任何意義,因為您無法強制執行它。編寫代碼是作者和讀者之間的對話,將結構公開并擁有構造函數會告訴讀者 - 這里你有構造函數,但你也有一個公共結構,這意味著構造函數的使用是任意的。如果是這種情況,請采用該設置

TA貢獻1828條經驗 獲得超3個贊
在大多數情況下,構造函數返回具體類型(或指向類型的指針)。返回接口可能是一個好主意的情況是當調用工廠函數或構建器函數時,其中底層具體類型滿足該接口。
error
例如,考慮接口,當你調用http.NewRequest
底層集中錯誤類型可以是 of等net.Error
。net.DNSError
現在嘗試思考如果函數返回具體類型,你將如何在沒有接口的情況下創建這樣的 api error
?我能想到的唯一解決方案是為net
包創建一個巨大的錯誤類型并添加額外信息的字段,但它很可能更難以維護,測試這種錯誤類型,更不用說內存膨脹了。
無論您選擇返回具體類型還是接口都是設計選擇,都存在一些準則來為常見場景提供解決方案。
- 3 回答
- 0 關注
- 146 瀏覽
添加回答
舉報