이 글은 위 전자책을 보고 정리한 내용입니다
Go에서 Slice를 생성하면 3개의 워드(word) 데이터 구조가 만들어집니다
1번 워드는 배열의 위치를 가르키며
2번 워드는 슬라이스의 길이를
3번 워드는 슬라이스의 총 용량을
보통 배열(Array)에서는 [10]이라면 타입에 따라 4byte(int)*10 = 40byte를 용량, 길이는 10이라고 정의하지만
Go의 Slice에서는 조금 다릅니다
slice2 := make([]string, 5, 8)
이렇게 만든다면 옆에 그림처럼
길이가 5인 그리고 용량은 8인
slice를 생성하죠
즉 첫 5개의 요소에 대해 읽고 쓸 수 있으며 ,
필요시 이용 가능한 3개의 용량을 갖는 것!
그렇다면 동적으로 슬라이스 만들 수 있다라고 볼 수 있겠죠
슬라이스의 슬라이스
slice3 := slice2[2:4]
slice2의 인덱스 2, 인덱스 3의 값을 갖는 slice3을 생성했습니다 여기서 slice3의 길이는 2이고 용량은 6입니다
이렇게 만들면 보통 slice3는 slice2의 값만 가져오지 주소를 공유하지 않습니다 하지만 Go의 slice에서는 참조라는 방식으로 움직입니다
=> Slice of slice (before)
Length[5] Capacity[8]
[0] 0xc00007e000 Apple
[1] 0xc00007e010 Orange
[2] 0xc00007e020 Banana
[3] 0xc00007e030 Grape
[4] 0xc00007e040 Plum
Length[2] Capacity[6]
[0] 0xc00007e020 Banana
[1] 0xc00007e030 Grape
저희는 위에서 slice2에 대해 정의를 했습니다 길이는 5이고 용량은 8이라고 그리고 안에 값을 넣고 slice3에 slice2[2~3] 주소를 넣어줬습니다 보이시나요? slice3의 0번째 1번째 인덱스의 주소와 값이 동일하게 공유하고 있는 점이??
이렇게 보이듯이 slice2의 값을 바꾼다면 slice3도 변경된다는 것을 우리는 이제 알았습니다
slice3 := slice2[2:4:4]
그렇다면 이렇게 하면 어떨까요?
바뀐 slice3은 slice2의 2번째 포인터를 가르키고 길이는 4이며 용량도 4입니다
길이와 용량이 같은 슬라이스에 대해 append가 호출 되면, slice2의 4번째 원소를 가지고 오지 않습니다
여전히 slice3와 slice2는 같은 배열을 공유하고 있지만 append가 호출 된다면 길이와 용량이 달라지게 됩니다 주소 또한 달라지죠
만약 여기서 append를 쓴다면 길이가 3인 새로운 슬라이스가 생기게 됩니다 더이상 slice2의 영향을 받지 않는 것이죠!
go에 slice는 배열 같으면서 주소를 공유함으로써 문제가 생길수 있다는 점에서 신기해서 글을 써봤습니다
'Go' 카테고리의 다른 글
[Go] Go의 웹 프레임워크 Gin이란? (0) | 2023.04.29 |
---|---|
[Go] Go로 로그 패키지 만들기 (1) (1) | 2023.03.07 |
[Go] Go루틴이란 무엇인가? (0) | 2023.02.16 |
[Go] struct를 생성하고 error코드 작성하기 (0) | 2023.01.09 |
[Go] append와 가비지 컬렉터의 관계 & if, switch문 알아보기 (0) | 2023.01.09 |