[Golang] Go 언어 배열과 슬라이스(순회, 추가, 복사)
포스트
취소

[Golang] Go 언어 배열과 슬라이스(순회, 추가, 복사)

Go 언어 배열과 슬라이스

배열과 슬라이스의 선언

여기에서 배열과 슬라이스 타입의 변수를 어떻게 선언하는지 확인할 수 있다.

배열/슬라이스 순회하기(반복문)

for 반목문과 len() 함수를 이용해서 배열/슬라이스의 길이만큼 반복하면서 요소를 꺼내올 수 있다.

1
2
3
4
a := []int{1,2,3,4,5}
for i := 0 ; i < len(a) ; i++ {
    fmt.Println(a[i])
}

for ... range 반복문을 이용하면 전체 요소를 순회하면서 인덱스와 값을 가져올 수 있다.

1
2
3
4
a := []string{"A","B","C","D","E"}
for index, value := range a {
    fmt.Println("idx = ", index, ", value = ", value)
}

range 키워드를 사용하면 첫 번째 변수에는 현재 요소의 인덱스, 두 번째 변수에는 현재 요소의 값의 복사본이 반환된다.

만약 인덱스를 사용하고 싶지 않다면?

Go 언어에서는 사용하지 않는 변수가 있으면 에러처리한다.

그래서 사용하지 않는 변수는 없어야하는데, 만약 for ... range 반복문에서 인덱스는 제외하고 값만 가져오고 싶을 땐 어떻게 할까?

1
2
3
4
a := []int{10,11,12,13,14}
for _, value := range a {   // 언더바(_)
    fmt.Println("value = ", value)
}

인덱스 변수의 자리에 언더바(_)로 받게되면, Go 언어에서는 사용하지 않을 변수로 인식하고 에러처리하지 않는다.

참고로, for ... range 반복문에서 변수를 하나로만 받으면 그 변수는 인덱스를 받게된다.

1
2
3
4
5
6
7
8
9
10
11
12
a := []string{"A", "B", "C", "D", "E"}
for index := range a {
    fmt.Println("idx = ", index)
}
/*
출력 결과
idx =  0
idx =  1
idx =  2
idx =  3
idx =  4
*/

슬라이싱

부분 슬라이스(Sub-Slice)를 추출한다고 말한다.

[:] 연산자로 배열이나 슬라이스의 일부분을 추출할 수 있는 기능이다. 파이썬과 동일하다.

s[n:m] : s 슬라이스의 n 번째 요소부터 m-1 번째 요소까지 추출

1
2
3
4
5
6
s := []int{0,1,2,3,4,5}
fmt.Println(s, " sub -> ", s[:2], s[2:4], s[4:])
/*
출력 결과
[0 1 2 3 4 5]  sub ->  [0 1] [2 3] [4 5]
*/

슬라이스에 요소 추가, 삽입

크기가 고정된 배열과 달리 슬라이스는 자유롭게 요소를 추가할 수 있다.

슬라이스 요소 추가

append() 함수를 이용하면 슬라이스에 요소를 추가할 수 있는데,

슬라이스의 자료형과 동일한 값을 추가하거나, 다른 슬라이스를 추가할 수 있다.

append(slice객체, 추가할 요소1, 추가할 요소2, …)

첫 번째 매개변수로 슬라이스 객체를 입력하고, 두 번째부터 추가할 요소의 값을 입력해주면 입력한 요소의 값이 슬라이스에 추가된다.

1
2
3
4
5
6
7
8
9
s := []int{0, 1}
fmt.Println(s)
s = append(s, 2, 3, 4)
fmt.Println(s)
/*
출력 결과
[0 1]
[0 1 2 3 4]
*/

append() 함수가 슬라이스에 요소를 추가할 때, 슬라이스 용량이 남아있는 경우 슬라이스의 길이를 변경하여 데이터를 추가하고,

용량을 초과하는 경우 현재 용량의 2배인 새로운 슬라이스를 만들어 기존 값을 복제한 뒤 데이터를 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
s := make([]int, 0, 3)

for i := 1; i <= 15; i++ {
    s = append(s, i)
    fmt.Printf("len = %2d, cap= %2d\n", len(s), cap(s))
}
}
/*
출력 결과
len =  1, cap=  3
len =  2, cap=  3
len =  3, cap=  3
len =  4, cap=  6
len =  5, cap=  6
len =  6, cap=  6
len =  7, cap= 12
len =  8, cap= 12
len =  9, cap= 12
len = 10, cap= 12
len = 11, cap= 12
len = 12, cap= 12
len = 13, cap= 24
len = 14, cap= 24
len = 15, cap= 24
*/

슬라이스 복사

슬라이스의 모든 요소를 다른 슬라이스로 복사할 때는 copy()함수를 이용한다.

copy(붙여넣읋 슬라이스, 복사할 슬라이스)

붙여넣을 슬라이스에는 미리 공간을 할당해놓아야하고 (빈 슬라이스에는 복사할 수 없다.)

할당되어있는 공간을 초과해서 복사되지는 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
a := []int{1, 2, 3, 4, 5}
b := make([]int, 3)

copy(b, a)     // a 슬라이스의 요소를 b 슬라이스에 복사
fmt.Println(b) // b 슬라이스의 공간이 3개이므로 3개만 복사된다.

b[0] = 6
fmt.Println(a) // b 슬라이스의 요소를 변경한다고 a 슬라이스의 요소가 바뀌지 않는다.
fmt.Println(b)
/*
출력 결과
[1 2 3]
[1 2 3 4 5]
[6 2 3]
*/

주의사항

copy() 함수를 이용하지 않고 슬라이싱으로 복사한다면 슬라이스는 참조타입이기 때문에 원본 데이터에 영향을 줄 수 있다.

슬라이스 정렬 패키지(sort)

Go 언어의 기본 라이브러리인 sort 패키지에 슬라이스와 관련된 다양한 함수들이 있다.

여기서 기본적인 슬라이스 정렬 함수들은 이해가 쉬운데, 인터페이스 타입의 슬라이스를 정렬하는 방법은 생각보다 복잡하다.

아래는 이해를 위해 참고한 자료들이다.

  • https://pkg.go.dev/sort#Sort
  • https://pkg.go.dev/sort#Interface
  • https://up-to-date-items.tistory.com/61
  • http://gyus.me/?p=592
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.

[Golang] Go 언어 반복문(for)

[minikube] minikube start 수행 시 The docker driver should not be used with root privileges 에러 발생