구조체의 배열 비교가 서로 다른 결과를 낳는 이유
Go에서 빈 구조의 배열을 비교하면 예상치 못한 결과가 발생할 수 있습니다. 이 동작은 언어에 있는 포인터와 크기가 0인 변수의 미묘한 특성에서 비롯됩니다.
크기가 0인 변수에 대한 포인터
Go 사양에 따르면 크기가 0인 개별 변수에는 반드시 고유한 주소가 있는 것은 아닙니다. 이는 크기가 0인 변수가 컴파일러에 의해 최적화되어 예측할 수 없는 메모리 할당이 발생할 수 있기 때문입니다.
예
다음 코드를 고려하세요.
var s, ss struct{} // two empty structs arr1 := [6]*struct{}{&s} // array with empty struct pointer arr2 := [6]*struct{}{&ss} // array with empty struct pointer fmt.Println(&s == &ss, arr1 == arr2) // false, true
이 예에서 arr1과 arr2는 별개의 빈 구조인 s와 arr2에 대한 포인터를 포함하는 두 개의 배열입니다. 봄 여름 시즌. 놀랍게도 arr1 == arr2 비교는 true를 반환합니다. 이는 컴파일러가 서로 다른 ID에도 불구하고 s와 ss를 동일한 주소에 배치했을 수 있기 때문입니다. 그러나 &s == &ss는 포인터 자체를 직접 비교하기 때문에 false로 평가됩니다.
구조체의 Int 변수
그러나 0이 아닌 값이 정수와 같은 구조의 경우 비교 동작이 변경됩니다.
var l, ll struct{A int}{} arr3 := [6]*struct{A int}{&l} // array with empty struct pointer arr4 := [6]*struct{A int}{&ll} // array with empty struct pointer fmt.Println(&l == &ll, arr3 == arr4) // false, false
이 경우 비교 동작은 arr3 및 arr4는 false를 반환하여 배열이 동일하지 않음을 나타냅니다. 이는 구조체에 저장된 0이 아닌 정수가 고유한 주소를 제공하기 때문입니다.
이스케이프 분석 및 변수 재배치
예상치 못한 동작도 이스케이프 분석의 영향을 받을 수 있습니다. , 변수를 힙이나 스택에 할당해야 하는지 여부를 결정하는 컴파일러 최적화입니다. 변수가 로컬 범위를 벗어나면 프로그램의 다른 부분에서 접근성을 보장하기 위해 힙에 할당됩니다.
빈 구조체에 대한 포인터의 경우 이스케이프되면 컴파일러는 이를 다음 위치로 재배치할 수 있습니다. 다른 힙 주소. 이러한 재배치는 동등 비교에 영향을 미쳐 false가 됩니다.
위 내용은 Go에서 빈 구조의 배열 비교가 때때로 예상치 못한 결과를 낳는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!