2 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超13個(gè)贊
當(dāng)你有一個(gè)int
類型的變量時(shí),你想寫一個(gè)函數(shù)來(lái)遞增它的值,你該怎么做?您要么將指針傳遞給變量,要么返回必須分配給原始變量的增量值。
例如(在Go Playground上試試):
func inc(i int) int { i++; return i }
var i int = 2
inc(i)
fmt.Println(i) // This will be 2
在上面的代碼中,您將i其inc()遞增并返回其值。原件i當(dāng)然不會(huì)變,i里面inc()只是一個(gè)副本,獨(dú)立于原件i。要更改原件,您必須評(píng)估返回值:
i = inc(i)
或者首先使用指針(在Go Playground上嘗試):
func inc(i *int) { *i++ }
var i int = 2
inc(&i)
fmt.Println(i) // This will be 3
切片也是如此。如果您想要/必須修改切片標(biāo)頭(這是一個(gè)數(shù)據(jù)指針、長(zhǎng)度和容量,請(qǐng)參閱參考資料reflect.SliceHeader
),您要么必須將指針傳遞給該切片(不是很常見),要么必須返回修改后的新切片您必須在呼叫者處分配的標(biāo)頭。這是更常用的解決方案,這也是內(nèi)置函數(shù)遵循的方法append()
。
當(dāng)您切片時(shí),(例如someslice[min:max]
),新切片將與原始切片共享支持?jǐn)?shù)組。這意味著如果您修改新切片的元素,原始切片也會(huì)觀察到這些更改。因此,如果您從新切片中刪除一個(gè)元素并將元素復(fù)制到被刪除元素的位置,則原始切片的最后一個(gè)元素仍將在那里,它被原始切片“覆蓋”。通常的做法是將最后一個(gè)元素置零,以便垃圾收集器可以回收它的內(nèi)存,如果它是指針類型(或“類似”如切片、映射或通道)。
我怎樣才能避免有一個(gè)“輸出切片”?(以正確的方式打印,包含正確的元素,具有預(yù)期的長(zhǎng)度和容量)
正如這個(gè)答案中所述:您必須將一個(gè)指針傳遞給您的切片,并修改 中的指向值FindAndRemoveFromFooSlice()
,因此您不必返回新切片。
為什么我嘗試“刪除就地”導(dǎo)致“輸入切片”的長(zhǎng)度與過濾過程之前的長(zhǎng)度相同?
你從來(lái)沒有修改過原始切片,你傳遞了它所以制作了一個(gè)副本,并且在內(nèi)部FindAndRemoveFromFooSlice()
你只能修改副本(但你甚至沒有修改副本)。你返回一個(gè)新的切片,但你沒有分配它,所以原來(lái)的切片(頭)是完整的。
為什么“輸入切片”的長(zhǎng)度與我應(yīng)用過濾過程之前的長(zhǎng)度相同?如何進(jìn)行刪除操作以更改“輸入切片”的長(zhǎng)度?
前兩個(gè)問題回答了這個(gè)問題。

TA貢獻(xiàn)1770條經(jīng)驗(yàn) 獲得超3個(gè)贊
最小工作代碼示例(帶有注釋以提供一些上下文):
// use a pointer for the input slice so then it is changed in-place
func FindAndRemoveFromFooSliceInPlace(iFilter int, inSl *[]FooItem) *FooItem {
? ? pointedInSl := *inSl // dereference the pointer so then we can use `append`
? ? inLen := len(pointedInSl)
? ? for idx, elem := range pointedInSl {
? ? ? ? if elem.Id == iFilter {
? ? ? ? ? ? log.Printf("Loop ID %v", idx)
? ? ? ? ? ? // check these docs: https://github.com/golang/go/wiki/SliceTricks#delete
? ? ? ? ? ? pointedInSl = append(pointedInSl[:idx], pointedInSl[idx+1:inLen]...)
? ? ? ? ? ? pointedInSl = pointedInSl[:inLen-1]
? ? ? ? ? ? *inSl = pointedInSl // assigning the new slice to the pointed value before returning
? ? ? ? ? ? return &elem
? ? ? ? }
? ? }
? ? return nil
}
- 2 回答
- 0 關(guān)注
- 158 瀏覽
添加回答
舉報(bào)