>백엔드 개발 >Golang >Go의 슬라이스 범위 루프를 지도와 ​​함께 사용할 때 왜 예상치 못한 동작이 발생합니까?

Go의 슬라이스 범위 루프를 지도와 ​​함께 사용할 때 왜 예상치 못한 동작이 발생합니까?

Linda Hamilton
Linda Hamilton원래의
2024-12-09 01:54:12394검색

Why Does Go's Slice Range Loop Create Unexpected Behavior When Used with Maps?

Go의 슬라이스 범위 동작 디코딩

Go에서 슬라이스는 동적 배열과 같은 기능을 제공하는 다목적 데이터 구조입니다. 슬라이스를 반복할 때 범위 구문은 해당 요소에 액세스하는 편리한 방법을 제공합니다. 그러나 특정 시나리오에서는 예상치 못한 동작이 발생할 수 있습니다.

학생 구조체 조각을 생성하고 이러한 구조체에 대한 참조로 지도를 채우는 다음 코드를 고려해 보세요.

type student struct {
    Name string
    Age  int
}

func main() {
    m := make(map[string]*student)
    s := []student{
        {Name: "Allen", Age: 24},
        {Name: "Tom", Age: 23},
    }

    for _, stu := range s {
        m[stu.Name] = &stu
    }

    fmt.Println(m) // map[Allen:0xc42006a0c0 Tom:0xc42006a0c0]
}

예상되는 동작은 다음과 같습니다. 지도에는 조각의 각 개별 학생 구조체에 대한 참조가 포함되어야 합니다. 그러나 결과는 맵의 두 키가 모두 동일한 주소를 가리키는 것으로 나타났습니다.

이 동작은 범위 루프의 stu 변수가 참조가 아닌 슬라이스 요소의 복사본이라는 점을 이해하면 설명할 수 있습니다. stu.Name은 이름 필드의 복사본을 검색하고 &stu는 복사본의 주소를 가져오므로 모든 맵 값에 대해 동일한 주소가 생성됩니다.

이 문제를 해결하려면 코드가 복사본의 주소를 가져와야 합니다. 대신 실제 슬라이스 요소:

for i := range s {
    m[s[i].Name] = &s[i]
}

슬라이스 요소에 직접 액세스하여 고유한 메모리 위치에 대한 참조를 얻어 예상치 못한 동작을 해결하고 지도에 각 학생에 대한 참조가 포함되도록 합니다. 구조체.

위 내용은 Go의 슬라이스 범위 루프를 지도와 ​​함께 사용할 때 왜 예상치 못한 동작이 발생합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.