Go 언어 Slice의 특징

byron1st·2020년 12월 14일
0
  • array는 고정된 크기를 갖는다. 반면 slice는 내부적으로 len, cap, 그리고 array에 대한 포인터로 구성된 구조체로, 편리한 사용을 위한 array 래퍼 구조체로 보면 좋다. Java의 Vector와 매우 유사하다.
  • sliceappend 함수로 아이템을 추가하는데, lencap이 같아지면, cap을 2배로 키우고, 새로운 array를 만든다.
package main

import (
	"fmt"
)

func main() {
	slice := make([]int, 0)
	
	for i := 0; i < 10; i++ {
		slice = append(slice, i)
		
		fmt.Printf("pointer: %p, cap: %d\n", slice, cap(slice))
	}
}

예를 들어, 위의 코드는 아래와 같은 결과를 준다.

pointer: 0xc0000b4020, cap: 1
pointer: 0xc0000b4040, cap: 2 // New array object
pointer: 0xc0000be020, cap: 4 // New array object
pointer: 0xc0000be020, cap: 4
pointer: 0xc0000c0000, cap: 8 // New array object
pointer: 0xc0000c0000, cap: 8
pointer: 0xc0000c0000, cap: 8
pointer: 0xc0000c0000, cap: 8
pointer: 0xc0000b2080, cap: 16 // New array object
pointer: 0xc0000b2080, cap: 16

그러므로, 미리 크기를 알고 있는 경우, array로 선언하는게 slice로 해서 append 함수를 쓰는 것 보다 성능 상 이점이 있다고 할 수 있다.

아니면, cap 값을 미리 지정해서 slice를 생성하면, 당연하겠지만, 새로운 array를 만들지 않는다. 그러니 전체 길이를 아는 배열을 만든다면, cap 값을 미리 지정해주는 것이 좋다.

package main

import (
	"fmt"
)

func main() {
	slice := make([]int, 0, 10)
	
	for i := 0; i < 10; i++ {
		slice = append(slice, i)
		
		fmt.Printf("pointer: %p, cap: %d\n", slice, cap(slice))
	}
}
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10
pointer: 0xc00009e000, cap: 10 // Same array object

slicecap을 키우며 새로운 array 객체를 만들때는 shallow-copy를 수행한다. 즉, 객체를 통째로 복사하지 않고 포인터 값만 가져온다. immutability를 고려한다면 주의하길.

slice를 만들 때, len 값을 0보다 큰 값을 넣으면, 일단 Zero value로 넣으며, 그 상태에서 append를 쓰면 당연히 그 이후의 index 값부터 채워넣는다.

package main

import (
	"fmt"
)

func main() {
	slice := make([]int, 5)
	
	for i := 0; i < 5; i++ {
		slice = append(slice, i)
		
		fmt.Printf("%v\n", slice)
	}
}
[0 0 0 0 0 0]
[0 0 0 0 0 0 1]
[0 0 0 0 0 0 1 2]
[0 0 0 0 0 0 1 2 3]
[0 0 0 0 0 0 1 2 3 4]
profile
Hyperledger Fabric, React/React Native, Software Architecture

0개의 댓글