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

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

是否可以從分配的返回值推斷類型參數?

是否可以從分配的返回值推斷類型參數?

Go
藍山帝景 2022-12-13 10:41:55
假設我寫了兩個這樣的函數:func ToInterfaceSlice[T any](s []T) []interface{} {    res := make([]interface{}, len(s))    for i, v := range s {        res[i] = v    }    return res}func FromInterfaceSlice[T any](s []interface{}) (res []T, err error) {    res = make([]T, len(s))    for i, v := range s {        vt, ok := v.(T)        if !ok {            return nil, fmt.Errorf("%v (type=%T) doesn't fit the target type %T", v, v, res)        }        res[i] = vt    }    return}當我從輸入參數解析類型時,我可以簡單地使用    var m = []int{1, 2, 3}    fmt.Println(ToInterfaceSlice(m))編譯器知道T是int.但是,當我嘗試從返回變量傳遞類型時    var m []int    m, _ = FromInterfaceSlice([]interface{}{1, 2, 3})    fmt.Println(m)編譯器報錯:.\scratch.go:29:27: 無法推斷 T我必須在函數調用中顯式傳遞類型:    var m []int    m, _ = FromInterfaceSlice[int]([]interface{}{1, 2, 3})    fmt.Println(m)當接收者變量不是接口時,從返回類型推斷類型參數有什么困難嗎?還是干脆不執行,甚至故意不執行?評論后更新#1我知道a, b := GenericFunc()不能引用返回值的類型。目前 Go 確實有“這取決于”情況是否需要來自用戶輸入的顯式實例化。type Set[T comparable] map[T]struct{}func NewSet[T comparable](eles ...T) Set[T] {    s := make(Set[T])    for _, ele := range eles {        s[ele] = struct{}{}    }    return s}可以同時使用t := NewSet(1, 2, 3)and t := NewSet[string](),但var t NewSet[float64] = NewSet()現在不行,因為這個
查看完整描述

1 回答

?
猛跑小豬

TA貢獻1858條經驗 獲得超8個贊

當前的類型推斷規則是明確的。不考慮如何使用返回值:

類型推斷是基于

  • 類型參數列表

  • 用已知類型參數初始化的替換映射 M,如果有的話

  • 普通函數參數的(可能為空)列表(僅在函數調用的情況下)

從 Go 1.18 開始,可能會簡單地重寫您的函數以接受所需類型的參數;這也有不隱藏函數體內分配的好處:

func FromInterfaceSlice[T any](s []interface{}, dst []T) error {

    if len(s) != len(dst) {

        return errors.New("lengths don't match")

    }

    for i, v := range s {

        vt, ok := v.(T)

        if !ok {

            return nil, fmt.Errorf("%v (type=%T) doesn't fit the target type %T", v, v, res)

        }

        dst[i] = vt

    }

    return nil

}

并傳入具有所需長度的目標切片:


func main() {

    src := []interface{}{1, 2, 3}

    m := make([]int, len(src))

    _ = FromInterfaceSlice(src, m)

    fmt.Println(m)

}

如果您不能或不想事先確定切片的長度,則只能進行顯式實例化:


var m []int

m, _ = FromInterfaceSlice[int]([]interface{}{1, 2, 3})

//                        ^^^ explicit type argument

此外,類型參數仍然無法通過:=簡寫聲明推斷出來:


// what is m???

m, err := FromInterfaceSlice([]interface{}{1, 2, 3})


查看完整回答
反對 回復 2022-12-13
  • 1 回答
  • 0 關注
  • 127 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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