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

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

如何分配或返回受聯(lián)合約束的通用 T?

如何分配或返回受聯(lián)合約束的通用 T?

Go
侃侃爾雅 2022-11-08 14:37:46
換句話說,我如何為聯(lián)合類型集中的不同類型實現(xiàn)特定于類型的解決方案?鑒于以下代碼...type FieldType interface {    string | int}type Field[T FieldType] struct {    name         string    defaultValue T}func NewField[T FieldType](name string, defaultValue T) *Field[T] {    return &Field[T]{        name:         name,        defaultValue: defaultValue,    }}func (f *Field[T]) Name() string {    return f.name}func (f *Field[T]) Get() (T, error) {    value, ok := os.LookupEnv(f.name)    if !ok {        return f.defaultValue, nil    }    return value, nil}編譯器顯示錯誤:field.go:37:9: cannot use value (variable of type string) as type T in return statement有沒有辦法為所有可能FieldType的 s 提供實現(xiàn)?喜歡...func (f *Field[string]) Get() (string, error) {    value, ok := os.LookupEnv(f.name)    if !ok {        return f.defaultValue, nil    }    return value, nil}func (f *Field[int]) Get() (int, error) {    raw, ok := os.LookupEnv(f.name)    if !ok {        return f.defaultValue, nil    }    value, err := strconv.ParseInt(raw, 10, 64)    if err != nil {        return *new(T), err    }    return int(value), nil}歡迎任何提示。
查看完整描述

2 回答

?
天涯盡頭無女友

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

發(fā)生錯誤是因為涉及類型參數(shù)的操作(包括賦值和返回)必須對其類型集中的所有類型都有效。在 的情況下string | int,沒有從字符串初始化它們的值的通用操作。


但是,您仍然有幾個選擇:


類型切換T

您在類型切換中使用具有泛型類型的字段T,并將具有具體類型的值臨時設(shè)置為interface{}/ any。然后類型斷言接口返回T以返回它。請注意,此斷言是未經(jīng)檢查的,因此如果出于某種原因ret持有不在T. 當(dāng)然你可以用 comma-ok 檢查它,但它仍然是一個運行時斷言:


func (f *Field[T]) Get() (T, error) {

    value, ok := os.LookupEnv(f.name)

    if !ok {

        return f.defaultValue, nil

    }

    var ret any

    switch any(f.defaultValue).(type) {

    case string:

        ret = value


    case int:

        // don't actually ignore errors

        i, _ := strconv.ParseInt(value, 10, 64)

        ret = int(i)

    }

    return ret.(T), nil

}

類型切換*T

您可以進一步簡化上面的代碼并擺脫空接口。在這種情況下,您獲取T-type 變量的地址并打開指針類型。這是在編譯時完全類型檢查的:


func (f *Field[T]) Get() (T, error) {

    value, ok := env[f.name]

    if !ok {

        return f.defaultValue, nil

    }


    var ret T

    switch p := any(&ret).(type) {

    case *string:

        *p = value


    case *int:

        i, _ := strconv.ParseInt(value, 10, 64)

        *p = int(i)

    }

    // ret has the zero value if no case matches

    return ret, nil

}

請注意,在這兩種情況下,您都必須將T值轉(zhuǎn)換為interface{}/any才能在類型開關(guān)中使用它。您不能直接在T.


帶地圖模擬的游樂場os.LookupEnv:https ://go.dev/play/p/LHqizyNL9lP


查看完整回答
反對 回復(fù) 2022-11-08
?
飲歌長嘯

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

好的,如果使用反射,類型開關(guān)可以工作。


func (f *Field[T]) Get() (T, error) {

    raw, ok := os.LookupEnv(f.name)

    if !ok {

        return f.defaultValue, nil

    }


    v := reflect.ValueOf(new(T))


    switch v.Type().Elem().Kind() {

    case reflect.String:

        v.Elem().Set(reflect.ValueOf(raw))


    case reflect.Int:

        value, err := strconv.ParseInt(raw, 10, 64)

        if err != nil {

            return f.defaultValue, err

        }

        v.Elem().Set(reflect.ValueOf(int(value)))

    }


    return v.Elem().Interface().(T), nil

}

但是非常歡迎更好的解決方案;-)


查看完整回答
反對 回復(fù) 2022-11-08
  • 2 回答
  • 0 關(guān)注
  • 117 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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