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

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

通用切片參數(shù)和限制為切片類型的參數(shù)有什么區(qū)別?

通用切片參數(shù)和限制為切片類型的參數(shù)有什么區(qū)別?

Go
慕虎7371278 2022-11-08 15:11:46
考慮實(shí)驗(yàn)包slices。這個(gè)包是實(shí)驗(yàn)性的,所以我知道簽名可能會改變;我用它來說明問題。考慮這個(gè)包中兩個(gè)函數(shù)的簽名,slices.Contains并且slices.Grow:func Contains[E comparable](s []E, v E) boolfunc Grow[S ~[]E, E any](s S, n int) S的第一個(gè)參數(shù)Contains具有類型[]E(Es 的切片)和E受約束的comparable類型(可比較的類型)。Grow相反,第一個(gè)參數(shù)的類型為S(just S),受(基礎(chǔ)類型為 的切片的類型)S約束~[]EE但是,在具有此類參數(shù)的函數(shù)內(nèi)部允許的操作之間似乎沒有任何實(shí)際區(qū)別。如果我們聲明一些具有相同類型參數(shù)的假函數(shù),我們可以看到兩者都編譯得很好:正如預(yù)期的那樣,在這兩個(gè)函數(shù)中,我們可以len/ cap、append、range、 分配make和 索引[ ]。func fakeContains[E comparable](s []E, v E) {    fmt.Println(len(s), cap(s))    var e E    fmt.Println(append(s, e))    fmt.Println(make([]E, 4))    for _, x := range s {        fmt.Println(x)    }    fmt.Println(s[0])        fmt.Println(reflect.TypeOf(s).Kind())}func fakeGrow[S ~[]E, E any](s S, n int) {    fmt.Println(len(s), cap(s))    var e E    fmt.Println(append(s, e))    fmt.Println(make(S, 4))    for _, x := range s {        fmt.Println(x)    }        fmt.Println(s[0])        fmt.Println(reflect.TypeOf(s).Kind())}甚至在所有情況下都reflect.TypeOf(s).Kind()給予。reflect.Slice這些函數(shù)也可以用不同的類型進(jìn)行測試,并且都可以編譯:// compiles just finefunc main() {    type MyUint64 uint64    type MyUint64Slice []uint64    foo := []uint64{0, 1, 2}    fakeContains(foo, 0)    fakeGrow(foo, 5)    bar := []MyUint64{3, 4, 5}    fakeContains(bar, 0)    fakeGrow(bar, 5)    baz := MyUint64Slice{6, 7, 8}    fakeContains(baz, 0)    fakeGrow(baz, 5)}在我的理解中,唯一的實(shí)際區(qū)別是在slices.Grow參數(shù)s S 中不是 slice。它只限于切片類型。事實(shí)上reflect.TypeOf(s),當(dāng) arg 是 的實(shí)例時(shí)會給出不同的輸出type MyUint64Slice []uint64:Contains帶 args []E給出reflect.TypeOf(s) -> []uint64Grow帶 args S給出reflect.TypeOf(s) -> main.MyUint64Slice但是,對我來說,兩者之間的實(shí)際區(qū)別并不是很明顯。帶有代碼的游樂場:https ://gotipplay.golang.org/p/zg2dGtSJwuI問題這兩個(gè)聲明在實(shí)踐中是否等效?如果沒有,我應(yīng)該什么時(shí)候選擇一個(gè)而不是另一個(gè)?
查看完整描述

1 回答

?
犯罪嫌疑人X

TA貢獻(xiàn)2080條經(jīng)驗(yàn) 獲得超4個(gè)贊

如果您必須返回與參數(shù)相同(可能命名)類型的切片,這很重要。


如果您不必返回切片(僅返回一些其他信息,例如 abool以報(bào)告是否包含該值),則無需使用本身約束切片的類型參數(shù),您可以為元素使用類型參數(shù)只要。


如果必須返回與輸入相同類型的切片,則必須使用本身約束到切片的類型參數(shù)(例如~[]E)。


為了演示,讓我們看看這兩個(gè)實(shí)現(xiàn)Grow():


func Grow[S ~[]E, E any](s S, n int) S {

    return append(s, make(S, n)...)[:len(s)]

}


func Grow2[E any](s []E, n int) []E {

    return append(s, make([]E, n)...)[:len(s)]

}

如果您傳遞具有切片作為其基礎(chǔ)類型的自定義類型的切片,Grow()則可以返回相同類型的值。Grow2()不能:它只能返回一個(gè)未命名的切片類型的值:[]E。


和演示:


x := []int{1}


x2 := Grow(x, 10)

fmt.Printf("x2 %T len=%d cap=%d\n", x2, len(x2), cap(x2))


x3 := Grow2(x, 10)

fmt.Printf("x3 %T len=%d cap=%d\n", x3, len(x3), cap(x3))


type ints []int

y := ints{1}


y2 := Grow(y, 10)

fmt.Printf("y2 %T len=%d cap=%d\n", y2, len(y2), cap(y2))


y3 := Grow2(y, 10)

fmt.Printf("y3 %T len=%d cap=%d\n", y3, len(y3), cap(y3))

輸出(在Go Playground上試試):


x2 []int len=1 cap=12

x3 []int len=1 cap=12

y2 main.ints len=1 cap=12

y3 []int len=1 cap=12

如您所見Grow2(y, 10),接收一個(gè) type 的值main.ints,但它返回一個(gè) type 的值[]int。這不是我們想要的。


查看完整回答
反對 回復(fù) 2022-11-08
  • 1 回答
  • 0 關(guān)注
  • 86 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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