Golang에서 슬라이스에 추가하는 동안 문제가 발생했습니다.
package main
import (
"fmt"
)
func main() {
var slice = make([]int, 3, 4)
fmt.Println(slice) //[0,0,0]
slice[0] = 1
fmt.Println(slice) //[1 0 0]
slice = append(slice, 4) // works, new element gets added to the slice
fmt.Println(slice) // [1 0 0 4]
modifySlice(slice)
fmt.Println(slice) //[11 0 0 4]
}
func modifySlice(s []int) {
s[0] = 11
s = append(s, 2) // new element gets added to the slice inside function, but not visible to caller function.
s[2] = 3 // changes after append will not be visible to caller
fmt.Println(s) //[11 0 3 4 2]
}
산출
[0 0 0]
[1 0 0]
[1 0 0 4]
[11 0 3 4 2]
[11 0 3 4]
운동장으로 이동Link .
위의 문제를 이해하기 위해 슬라이스의 내부 표현을 자세히 살펴보겠습니다.
내부적으로 슬라이스는 세 가지로 표현됩니다.
type SliceHeader struct {
Pointer uintptr
Len int
Cap int
}
슬라이스가 기본 배열에 대한 포인터를 포함하더라도 그 자체가 값이라는 것을 이해하는 것이 중요합니다. 따라서 슬라이스를
modifySlice
에 전달할 때 기본 배열, 길이 및 배열 용량에 대한 포인터를 보유하는 구조체 값을 전달합니다. 여기서 주목해야 할 점은 슬라이스가 구조체에 대한 포인터가 아니라는 것입니다.슬라이스 헤더가 값으로 전달되더라도 헤더에는 배열 요소에 대한 포인터가 포함되어 있으므로
s[0] = 11
함수에서 슬라이스의 0번째 인덱스modifySlice
를 수정하면 기본 배열 요소가 변경되었습니다. 따라서 함수가 반환될 때 수정된 인덱스가 호출자 함수에 표시되었습니다.내부에 새로 추가된 요소
modifySlice
와 이후 변경 사항이 호출자 함수에 표시되지 않는 이유는 무엇입니까?해결책:
슬라이스에 추가한 후 값을 반환한 다음 원래 슬라이스에 할당합니다.
package main
import (
"fmt"
)
func main() {
var slice = make([]int, 3, 4)
fmt.Println(slice) //[0,0,0]
slice[0] = 1
fmt.Println(slice) //[1 0 0]
slice = append(slice, 4)
fmt.Println(slice) // [1 0 0 4]
slice = modifySlice(slice)
fmt.Println(slice) //[11 0 3 4 2]
}
func modifySlice(s []int) []int {
s[0] = 11
s = append(s, 2)
s[2] = 3
fmt.Println(s) //[11 0 3 4 2]
return s
}
운동장으로 이동link .
한 가지 고려해야 할 사항은 업데이트된 슬라이스를 반환하고 동일한 값에 할당하더라도 원래 길이와 용량이 변경되어 길이가 다른 새로운 기본 배열이 생성된다는 것입니다. 슬라이스 교체 전과 후의 길이와 용량을 확인하여 차이를 확인하세요.
fmt.Println(len(slice), cap(slice))
Reference
이 문제에 관하여(Golang에서 슬라이스에 추가하는 동안 문제가 발생했습니다.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/sanyuktaagrawal/gotcha-while-appending-to-slices-in-golang-3k6d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)