>백엔드 개발 >Golang >Go 슬라이스: '범위'를 사용하여 슬라이스 요소를 복사하면 때때로 공유 메모리 주소가 발생하는 이유는 무엇입니까?

Go 슬라이스: '범위'를 사용하여 슬라이스 요소를 복사하면 때때로 공유 메모리 주소가 발생하는 이유는 무엇입니까?

Linda Hamilton
Linda Hamilton원래의
2024-12-19 02:12:09487검색

Go Slices: Why Does Copying Slice Elements Using `range` Sometimes Lead to Shared Memory Addresses?

Go: 슬라이스에서 복사한 메모리 주소 재사용

Go에서 범위 함수는 슬라이스의 요소를 반복합니다. 그러나 일반적인 함정은 루프 변수에 대한 메모리 주소를 재사용하는 것입니다. 이로 인해 슬라이스 요소를 다른 데이터 구조에 복사하려고 할 때 예기치 않은 결과가 발생할 수 있습니다.

다음 코드 조각을 고려하세요.

// Regions is the collection of the Region model
type Regions []Region

// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
    output := make([]Model, len(*coll))
    for idx, item := range *coll {
        output[idx] = &item
    }
    return output
}

이 코드에서 루프 변수 항목은 포인터 참조입니다. *col 슬라이스의 요소에. 출력 슬라이스의 요소에 &item을 할당하면 여러 요소가 동일한 기본 Region 개체를 가리키게 됩니다. 이는 출력과 *coll이 항목에 대해 동일한 메모리 주소를 공유하기 때문에 발생합니다.

이 문제를 해결하려면 출력의 각 요소에 대해 Region 개체의 고유한 복사본을 생성해야 합니다. 이는 다음 코드 조각을 사용하여 달성할 수 있습니다.

// Returns the model collection as a list of models
func (coll *Regions) ToModelList() []Model {
    output := make([]Model, len(*coll))
    for idx, _ := range *coll {
        i := (*coll)[idx]
        output[idx] = &i
    }
    return output
}

이 수정된 코드에서 _는 *coll 범위에 대한 루프 변수로 사용됩니다. 이렇게 하면 각 반복마다 i의 새 복사본이 생성되어 루프 반복 전반에 걸쳐 메모리 주소가 재사용되는 것을 방지할 수 있습니다.

이러한 유형의 함정을 피하고 올바른 프로그램 실행을 보장하려면 Go 메모리 관리의 미묘한 차이를 이해하는 것이 중요합니다. .

위 내용은 Go 슬라이스: '범위'를 사용하여 슬라이스 요소를 복사하면 때때로 공유 메모리 주소가 발생하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

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