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

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

為什么 Go 中的 maps.Keys() 指定映射類型為 M?

為什么 Go 中的 maps.Keys() 指定映射類型為 M?

Go
喵喵時光機 2022-12-05 11:14:16
我實現(xiàn)了一個函數(shù)來獲取映射中的鍵(實際上有幾個版本,用于不同的類型),我更新它以在 Go 1.18 中使用泛型。然后我發(fā)現(xiàn)實驗庫已擴展以包含該功能,雖然我的實現(xiàn)幾乎相同,但函數(shù)聲明有一些我想更好地理解的差異。這是我的原始通用版本(我重命名了變量以匹配標(biāo)準(zhǔn)庫,以更好地突出顯示實際上是不同的):func mapKeys[K comparable, V any](m map[K]V) []K {    r := make([]K, 0, len(m))    for k := range m {        r = append(r, k)    }    return r}這是標(biāo)準(zhǔn)庫版本:func Keys[M ~map[K]V, K comparable, V any](m M) []K {    r := make([]K, 0, len(m))    for k := range m {        r = append(r, k)    }    return r}如您所見,主要區(qū)別在于額外的M ~map[K]V類型參數(shù),我將其省略并直接用于map[K]V函數(shù)的參數(shù)類型。我的函數(shù)有效,那么為什么我需要經(jīng)歷添加第三個參數(shù)化類型的額外麻煩呢?當(dāng)我寫我的問題時,我想我已經(jīng)找到了答案:能夠在真正映射的類型上調(diào)用函數(shù),但沒有直接聲明為映射,比如在這個DataCache類型上:type DataCache map[string]DataObject我的想法是,這可能需要~map符號,并且~只能在類型約束中使用,而不能在實際類型中使用。該理論的唯一問題是:我的版本在此類地圖類型上運行良好。所以我不知道它有什么用。
查看完整描述

1 回答

?
繁花如伊

TA貢獻2012條經(jīng)驗 獲得超12個贊

它在非常罕見的情況下是相關(guān)的,在這種情況下,您需要聲明一個函數(shù)類型的變量(而不調(diào)用它),并且您使用另一個在其定義中使用未導(dǎo)出類型的包中的命名映射類型實例化該函數(shù)。


當(dāng)您需要接受和返回定義的類型時,在函數(shù)簽名中使用命名類型參數(shù)最相關(guān),正如您正確猜測的那樣,正如@icza在此處回答的關(guān)于x/exp/slices包的問題。

您關(guān)于“代字號類型”只能用于接口約束的說法也是正確的。

現(xiàn)在,包中的幾乎所有函數(shù)x/exp/maps實際上并不返回命名類型M。唯一真正做到的是maps.Clone帶有簽名:

func Clone[M ~map[K]V, K comparable, V any](m M) M

然而,由于類型統(tǒng)一,在沒有近似約束的情況下聲明簽名仍然適用于定義的類型。從規(guī)格:~map[K]V

[...],因為定義D的類型和類型文字L永遠不會等價,統(tǒng)一將 D 的基礎(chǔ)類型與 L 進行比較

和一個代碼示例:

func Keys[K comparable, V any](m map[K]V) []K {

    r := make([]K, 0, len(m))

    for k := range m {

        r = append(r, k)

    }

    return r

}


type Dictionary map[string]int


func main() {

    m := Dictionary{"foo": 1, "bar": 2}

    k := Keys(m)

    fmt.Println(k) // it just works

}

游樂場:https ://go.dev/play/p/hzb2TflybZ9


附加命名類型參數(shù)M ~map[K]V相關(guān)的情況是當(dāng)您需要傳遞函數(shù)的實例化值時:


func main() {

    // variable of function type!

    fn := Keys[Dictionary]

    

    m := Dictionary{"foo": 1, "bar": 2}

    fmt.Println(fn(m))

}

游樂場:https ://go.dev/play/p/hks_8bnhgsf


如果沒有M ~map[K]V類型參數(shù),就不可能用定義的類型實例化這樣一個函數(shù)值。當(dāng)然你可以實例化你K的V函數(shù)


fn := Keys[string, int]

但是當(dāng)定義的映射類型屬于不同的包并引用未導(dǎo)出的類型時,這是不可行的:


package foo 


type someStruct struct{ val int }


type Dictionary map[string]someStruct

和:


package main


func main() {

    // does not compile

    // fn := Keys[string, foo.someStruct]


    // this does

    fn := maps.Keys[foo.Dictionary]

}


雖然,這似乎是一個相當(dāng)通俗的用例。


你可以在這里看到最終的游樂場:https ://go.dev/play/p/B-_RBSqVqUD


但是請記住,這x/exp/maps是一個實驗包,因此簽名可能會隨著未來的 Go 版本和/或當(dāng)這些函數(shù)被提升到標(biāo)準(zhǔn)庫中而改變。


查看完整回答
反對 回復(fù) 2022-12-05
  • 1 回答
  • 0 關(guān)注
  • 167 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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