Давайте добавим окончательный оператор печати, чтобы увидеть результат:
slice := make([]string, 0, 1)
fmt.Println(cap(slice))
appendString(slice, "a")
fmt.Println(slice)
И вывод будет (попробуйте на Go Playground ):
1
[]
Что правильно. Можно ожидать, что результат будет:
1
[a]
Причина, по которой это не так, заключается в том, что, хотя новый резервный массив не будет выделен, заголовок слайса в переменной slice
внутри main()
равен , а не изменен , он все равно будет удерживайте length = 0
. Изменяется только заголовок слайса, сохраненный в локальной переменной slice
внутри appendString()
(параметр), но эта переменная не зависит от значения slice
.
в main.
Если вы измените значение main slice
, вы увидите, что массив поддержки содержит новую строку:
slice := make([]string, 0, 1)
fmt.Println(cap(slice))
appendString(slice, "a")
fmt.Println(slice)
slice = slice[:1]
fmt.Println(slice)
Теперь вывод будет (попробуйте на Go Playground ):
1
[]
[a]
Именно поэтому встроенный append()
должен возвращать новый срез: потому что даже если новый вспомогательный массив не требуется, заголовок среза (который содержит длину) придется изменить (увеличить ) если добавлено более 0 элементов.
Вот почему appendString()
также должен вернуть новый срез:
func appendString(slice []string, newString string) []string {
slice = append(slice, newString)
return slice
}
или коротко:
func appendString(slice []string, newString string) []string {
return append(slice, newString)
}
Что вы должны переназначить, где вы используете:
slice := make([]string, 0, 1)
fmt.Println(cap(slice))
slice = appendString(slice, "a")
fmt.Println(slice)
И тогда вы сразу же получите ожидаемый результат (попробуйте на Go Playground ):
1
[a]