2016-10-12 1 views
13

Golang에서 나는 여행 세일즈맨 문제에 대해 스크램블 슬라이스 기능을 만들려고합니다. 이 작업을하는 동안 슬라이스 편집을 시작했을 때 스크램블 기능이 전달 될 때마다 다른 것을 알게되었습니다.golang 조각은 값을 전달합니까?

디버깅을 한 후 기능 내에서 슬라이스를 편집하는 것으로 알았습니다. 그러나 Golang은 "가치에 의한 전달"언어로되어 있기 때문에 어떻게 가능합니까?

https://play.golang.org/p/mMivoH0TuV

내가 무슨 뜻인지 보여줄 수있는 놀이터 링크를 제공하고 있습니다. 27 행을 제거하면 다른 출력을 얻게됩니다.이 출력은 인수로 전달 될 때 함수가 자체 슬라이스 복사본을 만들기 때문에 차이가 없어야합니다.
누군가 현상을 설명 할 수 있습니까?

답변

28

예, Go의 모든 값이 전달됩니다. 슬라이스도. 그러나 슬라이스 값은 헤더이며 백킹 배열의 인접 섹션을 설명하고 슬라이스 값은 요소가 실제로 저장되는 배열에 대한 포인터 만 포함합니다. 슬라이스 값에는 배열과 달리 요소가 포함되지 않습니다.

그래서 슬라이스를 함수에 전달하면 포인터를 포함하여이 헤더에서 같은 배킹 배열을 가리키는 복사본이 만들어집니다. 슬라이스의 요소를 수정하면 배킹 배열의 요소를 수정하므로 동일한 배킹 어레이를 공유하는 모든 슬라이스가 변경 사항을 "관찰"합니다.

reflect.SliceHeader 유형을 확인, 슬라이스 헤더에 무엇을 참조하십시오 :

type SliceHeader struct { 
    Data uintptr 
    Len int 
    Cap int 
} 

관련/가능한 중복 질문을 참조하십시오 : Are Golang function parameter passed as copy-on-write?

읽기 블로그 게시물 : Go Slices: usage and internals

+0

그렇게 할 수있는 솔루션을 함수 내부에서 슬라이스의 로컬 복사본을 만들 수 있습니다. 대신 그 편집? – duck

+1

@ user4901806 전달 된 슬라이스의 요소 (해당 백업 배열의 요소가 가리키는 요소)를 수정하지 않으려면 예를 복사합니다. – icza

+0

요소를 추가하면 원본 슬라이스에 추가되지 않는다고 가정합니다. – Sahas