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

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

為什么 append 修改傳遞的切片

為什么 append 修改傳遞的切片

Go
慕慕森 2021-12-20 16:36:33
我如何遍歷切片并將切片傳遞到當(dāng)前元素之外的某個(gè)地方?正如我們?cè)谖臋n中看到的那樣,似乎append()函數(shù)修改了底層切片。但無(wú)論如何我仍然不知道如何達(dá)到這一點(diǎn)。func main() {    args := []string{ "2", "3", "8" }    for i, _ := range args {        fmt.Println(append(args[:i], args[i+1:]...)) // or pass to function    }    fmt.Println(args)}結(jié)果:[3 8][3 8][3 8][3 8 8] // it is args now我的期望: [3 8] [2 8] [2 3]但是切片的容量是多少對(duì)我來(lái)說(shuō)是秘密,我不明白為什么我超過(guò)了它。
查看完整描述

3 回答

?
素胚勾勒不出你

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

性能是很大的原因。創(chuàng)建一個(gè)新切片并將所有元素復(fù)制到它上面是昂貴的,因此切片代碼不會(huì)無(wú)緣無(wú)故地復(fù)制。但是,如果超出了切片的容量,它會(huì)通過(guò)復(fù)制底層切片以適當(dāng)?shù)牧吭鲩L(zhǎng)。這意味著返回的切片append可能與您傳入的切片不同。


首選的使用方式是:


args = append(args, newarg)

如果您采用子切片,容量保持不變,但您對(duì)切片的看法會(huì)發(fā)生變化。這意味著丟失的元素仍然存在,但在新切片的邊界之外。


這解釋了代碼的奇怪輸出。您append每次都打印結(jié)果但不存儲(chǔ)該結(jié)果,這意味著args與您打印的結(jié)果不同。


初始args切片有 3 個(gè)元素大。對(duì)于每個(gè)索引i- 也就是說(shuō) for 0, 1and 2- 你取一個(gè)子切片args[:i]并將數(shù)組剩余部分的所有元素附加args[i+1:]到它。這意味著對(duì)于:


i    args[:i]     args[i+1]...   Result         args

0    {}           {"3", "8"}     {"3", "8"}     {"3", "8", "8"}

1    {"3"}        {"8"}          {"3", "8"}     {"3", "8", "8"}

2    {"3", "8"}   {}             {"3", "8"}     {"3", "8", "8"}

tl;dr 你應(yīng)該總是保存 的結(jié)果append,如果你想制作一個(gè)副本以便你可以改變它,那么你自己制作一個(gè)副本。


查看完整回答
反對(duì) 回復(fù) 2021-12-20
?
慕蓋茨4494581

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

Append 總是嘗試修改底層數(shù)組。


讓我們看一下循環(huán)的第一次執(zhí)行


append(args[:0], args[0+1:]...)

這樣做是將切片 {3,8} 附加到切片 {},因?yàn)?args[:0] 為您提供了一個(gè)在數(shù)組開(kāi)頭結(jié)束的空切片。這就是為什么你的數(shù)組作為 [3 8 8] 出現(xiàn)的原因,因?yàn)?3 8 被附加到數(shù)組中。在 wiki 上閱讀有關(guān)此內(nèi)容的更多信息。


您可以使用 make 設(shè)置默認(rèn)容量,即


args := make([]string, 0, CAPACITY)

您還可以檢查切片的容量


a := []int{1,2,3}

fmt.Println(cap(a))

>>> 3

最后,如果您不想像 Elwinar 的回答那樣每次都重新復(fù)制數(shù)組,我建議將兩個(gè)切片 a[:i] 和 a[i+1:] 傳遞給函數(shù)。


查看完整回答
反對(duì) 回復(fù) 2021-12-20
?
楊魅力

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

Go 編程語(yǔ)言規(guī)范


追加和復(fù)制切片


內(nèi)置函數(shù) append 和 copy 輔助常見(jiàn)的切片操作。對(duì)于這兩個(gè)函數(shù),結(jié)果與參數(shù)引用的內(nèi)存是否重疊無(wú)關(guān)。


可變參數(shù)函數(shù) append 將零個(gè)或多個(gè)值 x 附加到類型 S 的 s 中,該類型必須是切片類型,并返回結(jié)果切片,也是 S 類型。值 x 被傳遞給類型為 ...T 的參數(shù),其中 T是 S 的元素類型,適用相應(yīng)的參數(shù)傳遞規(guī)則。作為一種特殊情況, append 還接受可分配給類型 []byte 的第一個(gè)參數(shù)和字符串類型的第二個(gè)參數(shù),后跟 ...。這種形式附加字符串的字節(jié)。


append(s S, x ...T) S  // T is the element type of S

如果 s 的容量不足以容納附加值,則 append 分配一個(gè)新的、足夠大的底層數(shù)組,該數(shù)組既適合現(xiàn)有切片元素又適合其他值。否則, append 會(huì)重新使用底層數(shù)組。


s0 := []int{0, 0}

s1 := append(s0, 2)                // append a single element     s1 == []int{0, 0, 2}

s2 := append(s1, 3, 5, 7)          // append multiple elements    s2 == []int{0, 0, 2, 3, 5, 7}

s3 := append(s2, s0...)            // append a slice              s3 == []int{0, 0, 2, 3, 5, 7, 0, 0}

s4 := append(s3[3:6], s3[2:]...)   // append overlapping slice    s4 == []int{3, 5, 7, 2, 3, 5, 7, 0, 0}


var t []interface{}

t = append(t, 42, 3.1415, "foo")   //                             t == []interface{}{42, 3.1415, "foo"}


var b []byte

b = append(b, "bar"...)            // append string contents      b == []byte{'b', 'a', 'r' }

函數(shù) copy 將切片元素從源 src 復(fù)制到目標(biāo) dst 并返回復(fù)制的元素?cái)?shù)。兩個(gè)參數(shù)必須具有相同的元素類型 T,并且必須可分配給類型為 []T 的切片。復(fù)制的元素?cái)?shù)是 len(src) 和 len(dst) 中的最小值。作為一種特殊情況,copy 還接受可分配給類型 []byte 的目標(biāo)參數(shù),并帶有字符串類型的源參數(shù)。這種形式將字節(jié)從字符串復(fù)制到字節(jié)片中。


copy(dst, src []T) int

copy(dst []byte, src string) int

例子:


var a = [...]int{0, 1, 2, 3, 4, 5, 6, 7}

var s = make([]int, 6)

var b = make([]byte, 5)

n1 := copy(s, a[0:])            // n1 == 6, s == []int{0, 1, 2, 3, 4, 5}

n2 := copy(s, s[2:])            // n2 == 4, s == []int{2, 3, 4, 5, 4, 5}

n3 := copy(b, "Hello, World!")  // n3 == 5, b == []byte("Hello")

不要使用 append 覆蓋您的輸入。為您的輸出使用單獨(dú)的變量(函數(shù)參數(shù))。例如,


package main


import "fmt"


func main() {

    args := []string{"2", "3", "8"}

    fmt.Println(args)

    funcArg := make([]string, len(args)-1)

    for i := range args {

        copy(funcArg, args[:i])

        copy(funcArg[i:], args[i+1:])

        fmt.Println(funcArg)

    }

    fmt.Println(args)

}

輸出:


[2 3 8]

[3 8]

[2 8]

[2 3]

[2 3 8]


查看完整回答
反對(duì) 回復(fù) 2021-12-20
  • 3 回答
  • 0 關(guān)注
  • 184 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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