개발일기

Go - Slice의 len과 cap 본문

프로그래밍 언어/Go

Go - Slice의 len과 cap

Flashback 2022. 3. 16. 12:01
728x90
반응형

1. Slice란?

Slice는 배열의 일부분이다. 

Slice는 동적 타입의 배열로써, 컴파일 시점에 배열의 크기가 정해지는 특징을 가진 배열이다. 기존의 배열을 선언할 때는, 배열 크기를 지정해줘야 했지만 Slice는 선언할 때, 배열 크기를 지정하지 않는다.

Go를 계속 공부하다보면, 배열을 사용하는 것보다 슬라이스를 더욱 많이 사용하는 것을 확인할 수 있다. 그만큼 슬라이스가 편하고 융통성있기 때문이다.

 

2. Array와 Slice의 차이

package main

func main() {
    arr := [3]int // 배열 크기를 지정한 배열
    arr2 := []int // 배열 크기를 지정하지 않는 Slice

}
  • Array : 크기를 지정하여 선언한다.
  • Slice : 크기를 지정하지않고 선언한다.추가적으로 길이, 용량이라는 옵션을 추가할 수 있다.

 

3. Make 내장함수를 사용하여 Slice 생성

위와 같이 슬라이스를 생성할 때, 단순히 배열길이를 추가하지 않은 채로 슬라이스를 생성할 수 있다. 하지만 Go의 내장함수인 make를 사용하면 슬라이스의 타입, 길이(len), 용량(cap) 등에 대한 옵션을 추가하여 슬라이스를 생성할 수 있다.

 

  • len : 슬라이스의 길이를 나타낸다.(length) - 슬라이스의 요소 개수를 나타낸다.
  • cap : 슬라이스의 용량을 나타낸다.(capacity) - 정해진 용량만큼 슬라이스 재선언없이 슬라이스 요소를 추가할 수 있다.
make(슬라이스 타입, 슬라이스 길이, 슬라이스 용량)

slice := make([]int, 5, 10)
// 타입은 int형에 길이는 5, 용량은 10을 가진 슬라이스를 생성

make 내장함수를 사용하여 슬라이스를 생성할 때, 3번째 파라미터인 용량은 생략하고 선언할 수 있다.

 

slice[0] // 0
slice[1] // 0
...
slice[4] // 0

슬라이스를 초기화 선언했을 때, 슬라이스가 정수형일 경우 각각의 인덱스에는 0값이 들어간다.

 

3-1. 길이와 용량?

여기서 슬라이스의 길이와 용량에 대해 무슨 차이가 있는지 헷갈려하는 사람들이 많다. len은 단순히 현재 슬라이스에 몇 개의 요소가 포함되어져 있는지에 대한 개수를 나타낸다. 용량은 현재 슬라이스에 주소값의 변경없이 포함시킬 수 있는 요소의 개수를 나타낸다. 변수 또는 슬라이스 등에는 각각의 주소값이 존재한다.

이것을 확인해 보기위해서는 Go의 append함수를 사용하여 슬라이스에 값을 추가함으로써 확인할 수 있다.

 

4. append함수

package main

func main() {
   s := make([]int, 0, 4)
   // 새로운 슬라이스 변수 = append(기존의 슬라이스, 추가요소)
   s = append(s, 1)
   s = append(s, 2)
   s = append(s, 3)
   println(s[0], s[1], s[2]) // 실행결과 : 1 2 3
}

append함수는 다음과 같이 추가할 요소를 두번째 파라미터에 추가할 값을 적어 슬라이스에 값을 추가할 수 있다.

 

5. Slice 길이와 용량의 차이

package main

func main() {
   s := make([]int, 0, 5)
   for i := 0; i < 11; i++ {
       s = append(s, i)
       println(cap(s), len(s), s)
   }
   /*
    예살 실행 결과 : 
    5 1 [1/5]0x1400005af38
    5 2 [2/5]0x1400005af38
    5 3 [3/5]0x1400005af38
    5 4 [4/5]0x1400005af38
    5 5 [5/5]0x1400005af38
    10 6 [6/10]0x1400008e000
    10 7 [7/10]0x1400008e000
    10 8 [8/10]0x1400008e000
    10 9 [9/10]0x1400008e000
    10 10 [10/10]0x1400008e000
    20 11 [11/20]0x14000090000
   */
}

슬라이스의 용량에 대해 살펴보기 위해 append를 사용하여 슬라이스에 하나씩 요소들을 추가하였다. 슬라이스의 초기 용량을 초과할 경우, 슬라이스의 용량은 두배로 증가하며 주소값이 바뀌는 것을 확인할 수 있다. 뒷부분의 '[1/5]0x1400005af38'와 같은 부분은 '[길이/용량] 주소'를 나타낸다. 슬라이스의 용량이 초과하여 새로운 슬라이스를 할당하는 것을 '리슬라이싱'이라고 한다. 주소값이 바뀌는 것은 해당 변수가 새로운 변수로 할당되었다는 것을 나타낸다. 이 주소값을 통해 메모리 공간의 값에 접근하여 해당 값을 가져올 수 있다.


https://stackoverflow.com/questions/41668053/cap-vs-len-of-slice-in-golang

 

cap vs len of slice in golang

What is the difference between cap and len of a slice in golang? According to definition: A slice has both a length and a capacity. The length of a slice is the number of elements it contains. ...

stackoverflow.com

https://gosamples.dev/capacity-and-length/

 

Capacity and length of a slice in Go (Golang) | gosamples.dev

Learn what is the difference between length and capacity of a slice

gosamples.dev

 

Go 슬라이스의 길이와 용량에 대한 개념이 확실하지 않은 경우, 위의 두 포스트를 확인하면 이해하는데 도움이 될 것이다.

 

728x90
반응형

'프로그래밍 언어 > Go' 카테고리의 다른 글

Go - 함수의 정의 및 사용법  (0) 2022.08.03
Go - Map이란?  (0) 2022.03.29
Go - 배열 사용법  (0) 2022.03.15
Go - 함수의 사용법 및 응용  (0) 2022.03.15
Go - for, for-range 반복문  (0) 2022.03.14
Comments