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

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

如何從 Go 1.18 中的單個方法返回兩種不同的具體類型?

如何從 Go 1.18 中的單個方法返回兩種不同的具體類型?

Go
catspeake 2023-01-03 10:02:05
假設(shè)我有這段代碼:type Type1 struct {    Name string `json:"name,omitempty"`    Path string `json:"path"`    File string `json:"file"`    Tag  int    `json:"tag"`    Num  int    `json:"num"`}func LoadConfiguration(data []byte) (*Type1, error) {    config, err := loadConf1(data)    if err != nil {        return nil, err    }    confOther, err := loadConfOther1()    if err != nil {        return nil, err    }    // do something with confOther    fmt.Println("confOther", confOther)    if confOther.Tag == 0 {        config.Num = 5    }    // do something with config attributes of type1    if config.Tag == 0 {        config.Tag = 5    }    if config.Num == 0 {        config.Num = 4    }    return config, nil}func loadConf1(bytes []byte) (*Type1, error) {    config := &Type1{}    if err := json.Unmarshal(bytes, config); err != nil {        return nil, fmt.Errorf("cannot load config: %v", err)    }    return config, nil}func loadConfOther1() (*Type1, error) {    // return value of this specific type    flatconfig := &Type1{}    // read a file as []byte    // written as a fixed array to simplify this example    fileContent := []byte{10, 22, 33, 44, 55}    if err := json.Unmarshal(fileContent, flatconfig); err != nil {        return nil, fmt.Errorf("cannot read config %v", err)    }    return flatconfig, nil}唯一的公共功能是LoadConfiguration。它基于真實代碼,用于讀取 json 數(shù)據(jù)作為特定結(jié)構(gòu)。如果某些東西看起來沒用,那是因為我簡化了原始代碼。上面的代碼沒問題,但現(xiàn)在我想創(chuàng)建另一個名為“Type2”的結(jié)構(gòu)類型,并重新使用相同的方法將數(shù)據(jù)讀入 Type2 而無需復(fù)制和粘貼所有內(nèi)容。type Type2 struct {    Name  string                  `json:"name,omitempty"`    Path  string                  `json:"path"`    Map   *map[string]interface{} `json:"map"`    Other string                  `json:"other"`}基本上,我希望能夠調(diào)用LoadConfigurationType2。我可以接受調(diào)用特定方法,例如LoadConfiguration2,但我也不想復(fù)制和粘貼loadConf1和 loadConfOther1。有沒有辦法在 Go 1.18 中以慣用的方式做到這一點?
查看完整描述

1 回答

?
神不在的星期二

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

實際上,您問題中顯示的代碼除了將類型傳遞給錯誤并設(shè)置錯誤格式外,什么也沒做json.Unmarshal,因此您可以重寫函數(shù)以使其表現(xiàn)得像它一樣:


func LoadConfiguration(data []byte) (*Type1, error) {

    config := &Type1{}

    if err := loadConf(data, config); err != nil {

        return nil, err

    }

    // ...

}


// "magically" accepts any type

// you could actually get rid of the intermediate function altogether

func loadConf(bytes []byte, config any) error {

    if err := json.Unmarshal(bytes, config); err != nil {

        return fmt.Errorf("cannot load config: %v", err)

    }

    return nil

}

如果代碼實際上做的不僅僅是將指針傳遞給json.Unmarshal,它可以從類型參數(shù)中獲益。


type Configurations interface {

    Type1 | Type2

}


func loadConf[T Configurations](bytes []byte) (*T, error) {

    config := new(T)

    if err := json.Unmarshal(bytes, config); err != nil {

        return nil, fmt.Errorf("cannot load config: %v", err)

    }

    return config, nil

}


func loadConfOther[T Configurations]() (*T, error) {

    flatconfig := new(T)

    // ... code

    return flatconfig, nil

}

在這些情況下,您可以創(chuàng)建一個任一類型的新指針,new(T)然后json.Unmarshal負(fù)責(zé)將字節(jié)切片或文件的內(nèi)容反序列化到其中——前提是 JSON 實際上可以解組到任一結(jié)構(gòu)中。


頂層函數(shù)中的特定于類型的代碼應(yīng)該仍然不同,特別是因為您想要使用顯式具體類型實例化通用函數(shù)。所以我建議保留LoadConfiguration1and LoadConfiguration2。


func LoadConfiguration1(data []byte) (*Type1, error) {

    config, err := loadConf[Type1](data)

    if err != nil {

        return nil, err

    }

    confOther, err := loadConfOther[Type1]()

    if err != nil {

        return nil, err

    }


    // ... type specific code


    return config, nil

}

但是,如果特定于類型的代碼只是其中的一小部分,您可能可以為特定部分使用類型切換,盡管在您的情況下這似乎不是一個可行的選擇。我看起來像:


func LoadConfiguration[T Configuration](data []byte) (*T, error) {

    config, err := loadConf[T](data)

    if err != nil {

        return nil, err

    }

    // let's pretend there's only one value of type parameter type

    // type-specific code

    switch t := config.(type) {

        case *Type1:

            // ... some *Type1 specific code

        case *Type2:

            // ... some *Type2 specific code

        default:

            // can't really happen because T is restricted to Configuration but helps catch errors if you extend the union and forget to add a corresponding case

            panic("invalid type")

    }


    return config, nil

}

最小的游樂場示例:https ://go.dev/play/p/-rhIgoxINTZ


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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