여기에서 배열과 슬라이스 타입의 변수를 어떻게 선언하는지 확인할 수 있다.
a := []int{1,2,3,4,5}
for i := 0 ; i < len(a) ; i++ {
fmt.Println(a[i])
}
a := []string{"A","B","C","D","E"}
for index, value := range a {
fmt.Println("idx = ", index, ", value = ", value)
}
range
키워드를 사용하면 첫 번째 변수에는 현재 요소의 인덱스, 두 번째 변수에는 현재 요소의 값의 복사본이 반환된다.
Go 언어에서는 사용하지 않는 변수가 있으면 에러처리한다.
그래서 사용하지 않는 변수는 없어야하는데, 만약 for ... range
반복문에서 인덱스는 제외하고 값만 가져오고 싶을 땐 어떻게 할까?
a := []int{10,11,12,13,14}
for _, value := range a { // 언더바(_)
fmt.Println("value = ", value)
}
인덱스 변수의 자리에 언더바(_
)로 받게되면, Go 언어에서는 사용하지 않을 변수로 인식하고 에러처리하지 않는다.
참고로, for ... range
반복문에서 변수를 하나로만 받으면 그 변수는 인덱스를 받게된다.
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 번째 요소까지 추출
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, ...)
첫 번째 매개변수로 슬라이스 객체를 입력하고, 두 번째부터 추가할 요소의 값을 입력해주면 입력한 요소의 값이 슬라이스에 추가된다.
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배인 새로운 슬라이스를 만들어 기존 값을 복제한 뒤 데이터를 추가한다.
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(붙여넣읋 슬라이스, 복사할 슬라이스)
붙여넣을 슬라이스에는 미리 공간을 할당해놓아야하고 (빈 슬라이스에는 복사할 수 없다.)
할당되어있는 공간을 초과해서 복사되지는 않는다.
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()
함수를 이용하지 않고 슬라이싱으로 복사한다면 슬라이스는 참조타입이기 때문에 원본 데이터에 영향을 줄 수 있다.
Go 언어의 기본 라이브러리인 sort
패키지에 슬라이스와 관련된 다양한 함수들이 있다.
여기서 기본적인 슬라이스 정렬 함수들은 이해가 쉬운데, 인터페이스 타입의 슬라이스를 정렬하는 방법은 생각보다 복잡하다.
아래는 이해를 위해 참고한 자료들이다.