2 回答

TA貢獻1876條經(jīng)驗 獲得超5個贊
Slice 基本上只是對底層數(shù)組、起始指針、長度和容量的引用。因此,如果可能的話,請考慮以下事項:
sliceOfStrings := []string{"one", "two", "three"}
// prints ONE TWO THREE
for i := range sliceOfStrings {
fmt.Println(strings.ToUpper(sliceOfStrings[i]))
}
// imagine this is possible
var sliceOfInterface = []interface{}(sliceOfStrings)
// since it's array of interface{} now - we can do anything
// let's put integer into the first position
sliceOfInterface[0] = 1
// sliceOfStrings still points to the same array, and now "one" is replaced by 1
fmt.Println(strings.ToUpper(sliceOfStrings[0])) // BANG!
此問題存在于 Java 和 C# 中。在實踐中它很少發(fā)生,但仍然發(fā)生。鑒于在 Go 中沒有像 int32 -> int64 這樣的自動類型轉(zhuǎn)換,如果你真的想將 []string 作為 []interface{} 發(fā)送,你被迫創(chuàng)建一個 []interface{} 副本是有道理的。這樣就不會令人驚訝了 - 你明確地寫了它,你知道你在做什么。如果函數(shù)會修改 []interface{} - 它不會傷害原始的 []string。

TA貢獻1921條經(jīng)驗 獲得超9個贊
因為[]string
和[]interface{}
有不同的內(nèi)存布局。當您意識到一個interface{}
變量需要知道它所包含的值的類型時,這一點很明顯。
對于[]string
切片,后備數(shù)組只需要保存單個字符串。對于[]interface{}
切片,您已經(jīng)獲得了類型信息和字符串值(嗯,指向字符串值的指針,因為字符串大于內(nèi)存中的單個字)。因此,從一種類型轉(zhuǎn)換為另一種類型將涉及復制數(shù)據(jù)。
Go 自動執(zhí)行轉(zhuǎn)換會令人困惑,因為它會使代碼推理變得困難。例如,函數(shù)調(diào)用f(s)
可以修改切片中的字符串,s
如果它被聲明為接受一個[]string
參數(shù),但如果它被聲明為接受一個參數(shù),則不能[]interface{}
。
- 2 回答
- 0 關(guān)注
- 856 瀏覽
添加回答
舉報