亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何編寫慣用的構造函數

如何編寫慣用的構造函數

Go
明月笑刀無情 2023-08-07 14:47:27
我對 Go 中的構造函數感到困惑。我見過的大多數構造函數都會返回一個結構體,但是“Effective Go”表明,根據“通用性”規則,在某些情況下可以返回一個接口。我相信“Effective Go”能夠提供好的想法,但這似乎不遵循“接受接口,返回結構”的原則。我猜想許多類型都實現了一個接口,僅此而已,因此在這種情況下,很容易看到返回接口的構造函數。另一個相關的說法是接口應該由消費者定義,但“通用性”意味著接口由生產者定義。有人可以澄清一下嗎?
查看完整描述

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{}而在第二種情況下,我將無法這樣做,我被迫使用提供的構造函數。第一種情況還允許在創建后修改字段值,而第二種情況則不允許。使該字段不導出將解決第二部分,但不能解決第一部分。


這個例子顯然是微不足道的,但是能夠構造無效的結構可能會產生可怕的影響。通過使用特定的構造函數,您可以確保對象處于有效的起始狀態,并且您只需要確保它始終保持有效狀態。如果您不能確保這一點,您可能需要在每個方法開始時檢查它是否處于有效狀態。


例如,考慮一個數據庫請求。它需要數據庫連接。如果用戶能夠在沒有數據庫連接的情況下創建數據庫請求,您將必須檢查它在每種方法中是否有效。如果你強迫他使用構造函數,你可以在創建時檢查并完成。


查看完整回答
反對 回復 2023-08-07
?
30秒到達戰場

TA貢獻1828條經驗 獲得超6個贊

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



查看完整回答
反對 回復 2023-08-07
?
子衿沉夜

TA貢獻1828條經驗 獲得超3個贊

在大多數情況下,構造函數返回具體類型(或指向類型的指針)。返回接口可能是一個好主意的情況是當調用工廠函數或構建器函數時,其中底層具體類型滿足該接口。

error例如,考慮接口,當你調用http.NewRequest底層集中錯誤類型可以是 of等net.Error。net.DNSError現在嘗試思考如果函數返回具體類型,你將如何在沒有接口的情況下創建這樣的 api error?我能想到的唯一解決方案是為net包創建一個巨大的錯誤類型并添加額外信息的字段,但它很可能更難以維護,測試這種錯誤類型,更不用說內存膨脹了。

無論您選擇返回具體類型還是接口都是設計選擇,都存在一些準則來為常見場景提供解決方案。


查看完整回答
反對 回復 2023-08-07
  • 3 回答
  • 0 關注
  • 146 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號