이상한 Golang "추가" 동작: 슬라이스의 값 덮어쓰기
Golang에서는 슬라이스에 추가할 때 차이점을 이해하는 것이 중요합니다. 포인터 유형과 포인터가 아닌 유형 사이.
예제를 고려해보세요. 코드:
import "fmt" type Foo struct { val int } func main() { var a = make([]*Foo, 1) a[0] = &Foo{0} var b = [3]Foo{Foo{1}, Foo{2}, Foo{3}} for _, e := range b { a = append(a, &e) } for _, e := range a { fmt.Printf("%v ", *e) } }
예상되는 출력은 {0} {1} {2} {3}이지만 대신 {0} {3} {3} {3}을 인쇄합니다. 이는 for 루프가 배열 요소의 복사본에서 작동하기 때문입니다.
for ... 범위로 반복할 때 임시 루프 변수가 생성되고 배열 요소의 값이 할당됩니다. 이 경우 임시 변수는 Foo 유형입니다. 그러나 슬라이스에 추가할 때 실제 배열 요소의 주소 대신 임시 변수의 주소가 추가됩니다.
이 임시 변수는 각 루프 반복에서 마지막 요소의 값으로 덮어쓰여집니다. Foo{3}인 배열입니다. 결과적으로 슬라이스에는 배열의 마지막 요소를 가리키는 동일한 포인터에 대한 여러 참조가 포함되어 있습니다.
문제를 해결하려면 루프 변수 대신 배열 요소의 주소를 추가해야 합니다.
for i := range b { a = append(a, &b[i]) }
이 수정을 통해 예상한 대로 출력됩니다: {0} {1} {2} {3}.
이 동작은 이해의 중요성을 강조합니다. Go의 유형 시스템과 슬라이스 작업 시 포인터와 비포인터의 구별.
위 내용은 Go에서 슬라이스에 포인터를 추가하면 예기치 않은 덮어쓰기 값이 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!