Go 슬라이스의 예기치 않은 추가 동작: 설명
Go에서 포인터 슬라이스에 추가할 때 추가 기능이 흥미롭게 작동합니다. 이를 설명하기 위해 다음 코드를 고려하십시오.
코드가 {0} {1} {2} {3}를 인쇄할 것이라는 기대와는 달리 대신 {0} {3} { 3} {3}. 이러한 불일치의 원인은 for 루프의 범위 변수의 특성에 있습니다.
범위 변수 이해
Go의 for-range 루프는 복사본을 생성하여 작동합니다. 반복되는 배열 또는 슬라이스의 각 요소. 이 경우 e는 배열 b에 있는 요소의 복사본입니다. 따라서 e 자체는 b의 요소가 아닙니다. 오히려 요소의 값을 보유하는 임시 변수입니다.
슬라이스 a에 추가할 때 코드는 b의 실제 요소 주소가 아닌 e의 주소를 추가합니다. e는 모든 반복에 대해 동일한 복사본이므로 동일한 포인터가 a에 세 번 추가됩니다. 따라서 e(Foo{3})에 할당된 마지막 값은 반복적으로 인쇄되는 값입니다.
동작 수정
이 동작을 수정하려면 코드 e의 주소가 아닌 b의 실제 요소 주소를 추가해야 합니다. 수정된 루프는 다음과 같습니다.
&e 대신 &b[i]를 추가하면 코드는 b의 각 요소가 a에 추가되도록 합니다. 결과적으로 올바른 출력 {0} {1} {2} {3}이 인쇄됩니다.
초기 동작 이유
이 예상치 못한 동작은 Go의 실제 참고 자료입니다. Go에는 포인터 유형과 포인터가 아닌 유형이 있지만 참조는 없습니다. 범위 변수는 포인터이거나 포인터가 아닌 값을 보유하는 단순한 지역 변수입니다. 참조를 보유할 수 없습니다.
따라서 범위 변수에 대해 작업을 수행할 때 요소 자체가 아닌 값만 조작하게 됩니다. 실제 요소를 수정하려면 값을 범위 변수에 할당하여 값을 효과적으로 복사해야 합니다. 그러면 이 값은 다음 반복에서 덮어쓰여집니다.
위 내용은 범위 루프에서 포인터를 추가할 때 Go의 `append` 함수가 예상치 못한 결과를 생성하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!