第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

避免在 Go 中編寫過多的 getter 和 setter

避免在 Go 中編寫過多的 getter 和 setter

Go
慕慕森 2023-06-19 17:14:47
我正在 Go 中實現(xiàn)一個消息傳遞系統(tǒng)。所以我有一個名為Msg. 該Msg接口定義了許多公共字段,例如源、目標(biāo)、發(fā)送時間、接收時間等。我無法定義 s 的完整列表,Msg因為我希望庫用戶定義Msgs 的具體類型。要提供具體的 類型Msg,用戶需要實現(xiàn)大量的 getter 和 setter,這非常煩人。我嘗試過的一種解決方案是提供一個簡單的基類,MsgBase并定義所有公共屬性以及 getter 和 setter。對于 的每個具體類型Msg,我都嵌入了一個指向 的指針MsgBase。該解決方案有效。但是,我想MsgBase在具體Msg類型中嵌入一個值版本。這是因為這樣的Msgs 在執(zhí)行過程中創(chuàng)建了太多次,動態(tài)分配 aMsgBase會增加垃圾收集開銷。我真的希望所有的Msgs 都是靜態(tài)分配的,因為它們由組件傳遞并且永遠(yuǎn)不應(yīng)該共享。如果我使用 的值版本MsgBase,則無法使用 中定義的設(shè)置器MsgBase。我想知道這個問題是否有任何簡單的解決方案?編輯:添加示例代碼type Msg interface {    // Agent is another interface    Src() Agent    SetSrc(a Agent)    Dst() Agent    SetDst(a Agent)    ... // A large number of properties}type MsgBase struct {    src, dst Agent    ... // Properties as private fields.}func (m MsgBase) Src() Agent {    return m.src}func (m *MsgBase) SetSrc(a Agent) {    m.src = a}... // Many other setters and getters for MsgBasetype SampleMsg struct {    MsgBase // option1    *MsgBase // option2}
查看完整描述

1 回答

?
呼如林

TA貢獻(xiàn)1798條經(jīng)驗 獲得超3個贊

請記住,Go 不像 Java 那樣具有面向?qū)ο蟮睦^承。這聽起來像是您正在嘗試編寫一個抽象基類來封裝“消息”的所有部分;這不是真正典型的 Go 風(fēng)格。


您描述的字段是典型的消息元數(shù)據(jù)。您可以將此元數(shù)據(jù)封裝在純數(shù)據(jù)結(jié)構(gòu)中。它不一定需要任何行為,也不一定需要 getter 和 setter 方法。


type MessageMeta struct {

  Source Agent

  Destination Agent

}

更面向?qū)ο蟮姆椒ㄊ钦f一條消息有一個(可變的)元數(shù)據(jù)塊和一個(不可變的,編碼的)有效負(fù)載。


import "encoding"


type Message interface {

  encoding.BinaryMarshaler // requires MarshalBinary()

  Meta() *MessageMeta

}


type SomeMessage struct {

  MessageMeta

  Greeting string

}


func (m *SomeMessage) Meta() *MessageMeta {

  return &m.MessageMeta

}


func (m *SomeMessage) MarshalBinary() ([]byte, error) {

  return []byte(m.Greeting), nil

}

將這兩件事分開傳遞的更程序化的方法也是合理的。在這種情況下,沒有什么是“消息”的接口,您只需傳遞編碼的有效負(fù)載;像這樣的標(biāo)準(zhǔn)庫接口encoding.BinaryMarshaler在這里很有意義。您可以將其包含在屬于您的庫的較低級別的界面中。


func Deliver(meta *MessageMeta, payload []byte) error { ... }

將一個翻譯成另一個很容易


func DeliverMessage(m Message) error {

  payload, err := m.Payload()

  if err != nil {

    return err

  }

  meta := m.Meta()

  return Deliver(meta, payload)

}

如果其中一個元數(shù)據(jù)字段是“交付于”,確保在整個鏈中傳遞一個指向元數(shù)據(jù)對象的指針可以讓您更新原始對象中的該字段。


我不會擔(dān)心將垃圾收集作為首要考慮因素,除非是為了避免過度浪費,并在 GC 開始出現(xiàn)在配置文件中時檢查對象分配。創(chuàng)建兩個對象而不是一個對象在這里可能不會成為一個大問題。


查看完整回答
反對 回復(fù) 2023-06-19
  • 1 回答
  • 0 關(guān)注
  • 114 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號