8. 슬라이스(Slices)
: 슬라이스는 배열의 값을 가리키는 포인트이다. 그리고 배열의 길이를 가지고 있다. []T는 타입 T를 가지는 요소의 슬라이스(slice)이다. (https://blog.golang.org/go-slices-usage-and-internals)
func main() {
p := []int{2, 3, 5, 7, 11, 13}
fmt.Println("p ==", p)
for i := 0; i < len(p); i++ {
fmt.Printf("p[%d] == %d\n", i, p[i])
}
}
8.1. 슬라이스 자르기(Slicing slices)
: 슬라이스는 재분할 할 수도 있고, 같은 배열을 가리키는(point) 새로운 슬라이스를 만들 수 도 있다. 슬라이스를 자른다고 해서, 데이터를 복사하는 것이 아니다. 다만, 해당 데이터 만큼을 가리키는 포인터가 새롭게 생성 될뿐이다.
예제로 살펴보면
s[lo:hi] // = lo에서 hi-1까지
위의 표현은 lo 에서 hi-1 의 요소(element)를 포함하는 슬라이스입니다. 따라서
s[lo:lo]
는 빈(empty) 슬라이스 이고
s[lo:lo+1]
는 하나의 요소를 가집니다.
p := []int{2, 3, 5, 7, 11, 13}
fmt.Println("p ==", p) // [2 3 5 7 11 13]
fmt.Println("p[1:4] ==", p[1:4]) //[3 5 7]
// missing low index implies 0
fmt.Println("p[:3] ==", p[:3]) //= 0:3 = [2 3 5]
// missing high index implies len(s)
fmt.Println("p[4:] ==", p[4:]) //= 4:end = [11 13]
8.2. 슬라이스 만들기
: 슬라이스는 make함수로도 만들수 있다. 이렇게 생성된 슬라이스는 0을 할당한 배열을 생성하고, 그것을 참조(refer)한다.
a := make([]int, 5) // len(a)=5
make 함수의 세번째 매개변수로 용량(capacity)를 제한할 수 있다.
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:] // len(b)=4, cap(b)=4
func main() {
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c) //이때는 cap이 안줄어들지 않는다. 왜냐면 원본의 cap이 그대로이고, 시작점이, 0이기 때문에 줄어 들필요가 없다.
d := c[2:5]
printSlice("d", d) //하지만 이때는 cap이 줄어든다. 왜냐면 원본의 cap은 그대로이지만, 슬라이스한 시작점이 2부터이기때문에 해당 슬라이스 포인트가 가질수 있는 cap은 줄어든다.
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n", s, len(x), cap(x), x)
}
8.3. 빈 슬라이스
: 슬라이스의 zero value는 nil 이다. nil 슬라이스는 길이와 최대 크기가 0이다.
func main() {
var z []int
fmt.Println(z, len(z), cap(z))
if z == nil {
fmt.Println("nil!")
}
}