슬라이스 타입

슬라이스 타입 (Slice types)

Slices — Go에서 가장 일상적으로 만나는 동적 시퀀스 타입이죠. 배열이 길이를 고정한 채로 묶여 있다면, 슬라이스는 그 배열의 일부 구간을 가리키는 '설명서(descriptor)'처럼 동작해요. 배열과 어떻게 다르고, 왜 슬라이스를 쓰면 편한지 하나씩 풀어볼게요.

출처: Go Specification

본문

슬라이스(slice)는 *밑바탕 배열(underlying array)*의 연속된 구간을 나타내는 설명자(descriptor)이며, 그 배열에 속한 요소들을 번호가 매겨진 순서대로 접근할 수 있게 해줘요.

슬라이스 타입은 해당 요소 타입을 가진 배열의 모든 슬라이스들의 집합을 나타냅니다. 요소의 개수를 슬라이스의 길이(length)라고 부르며, 절대 음수가 될 수 없어요. 초기화되지 않은 슬라이스의 값은 nil입니다.

SliceType = "[" "]" ElementType .

슬라이스 s의 길이는 내장 함수인 len으로 알아낼 수 있는데, 배열과 달리 실행 중에 바뀔 수 있어요. 요소들은 정수 indices 0부터 len(s)-1까지로 접근할 수 있습니다. 어떤 요소의 슬라이스에서의 인덱스는 같은 요소가 밑바탕 배열에서 갖는 인덱스보다 작을 수 있어요.

한번 초기화된 슬라이스는 항상 그 요소들을 담고 있는 밑바탕 배열과 연결됩니다. 그래서 슬라이스는 자신의 배열, 그리고 같은 배열에서 만든 다른 슬라이스들과 저장 공간을 공유해요. 반대로 서로 다른 배열은 항상 서로 다른 저장 공간을 나타냅니다.

슬라이스의 밑바탕 배열은 슬라이스의 끝을 넘어서까지 확장될 수 있어요. *용량(capacity)*은 바로 그 확장 범위를 재는 척도인데, 슬라이스의 길이와 슬라이스 너머에 있는 배열의 길이를 합한 값이에요. 이 용량까지의 길이를 가진 슬라이스는 원래 슬라이스에서 새 것을 *슬라이싱(slicing)*해서 만들 수 있습니다. 슬라이스 a의 용량은 내장 함수인 cap(a)으로 알아낼 수 있어요.

주어진 요소 타입 T에 대해 새로 초기화된 슬라이스 값은 내장 함수 make로 만들 수 있는데, make는 슬라이스 타입과 길이, 그리고 선택적으로 용량을 지정하는 매개변수를 받아요. make로 만든 슬라이스는 항상 새롭고 숨겨진 배열을 할당하며, 반환된 슬라이스 값은 그 배열을 가리킵니다. 즉,

make([]T, length, capacity)

를 실행하면 배열을 할당하고 그 배열을 슬라이싱한 것과 같은 슬라이스가 생겨요. 그래서 다음 두 표현은 동등합니다.

make([]int, 50, 100)
new([100]int)[0:50]

배열과 마찬가지로 슬라이스도 항상 1차원이지만, 이들을 조합해 더 높은 차원의 객체를 만들 수 있어요. 배열의 배열에서는 안쪽 배열들이 구조상 항상 같은 길이를 갖지만, 슬라이스의 슬라이스(또는 배열의 슬라이스)에서는 안쪽 길이가 실행 중에 자유롭게 달라질 수 있습니다. 게다가 안쪽 슬라이스는 각각 따로 초기화해 줘야 해요.

더 알아보기