배열 사용하기
on Go
Golang 에서의 배열은 생성할 때 요소의 개수가 고정되어, 늘리거나 줄일 수 없는 등 길이가 변하지 않는 고정 길이 배열이다.
기본적으로 배열은 아래와 같은 방식들로 생성할 수 있다.
func main() {
var arr1 [5]int = [5]int{1, 2, 3, 4, 5}
var arr2 [5]int = [5]int{1, 2, 3}
arr3 := [5]int{1, 2, 3, 4, 5}
arr4 := [...]int{1, 2, 3}
var arr5 = [5]int{0:10, 2:-10, 4:99}
}
arr1 의 경우 다른 변수 선언과 비슷하게 var 키워드에 변수명과 변수타입을 붙여주는데, 이 때 변수 타입 앞에 배열 원소의 개수를 대괄호로 묶어주면 된다.
변수 선언시에 들어가는 원소의 개수는 반드시 상수여야 한다(변수값 사용 불가).
arr2 는 같은 방식으로 배열을 선언하고 초기화하지만, 5개짜리 배열에 값을 3개로만 초기화하고 있다.
이런 경우에는 배열의 앞에서부터 순서대로 값을 할당해주고, 나머지 남는 공간들에 대해서는 각 타입별 기본값으로 초기화된다(int의 경우 0).
arr3 에서 배열 역시 := 를 통한 선언 및 초기화를 지원하는 걸 확인할 수 있고, 배열의 초기화는 동일한 방식이다.
arr4 는 원소의 개수에 … 을 사용함으로써, 초기화를 위해 입력된 원소의 개수만큼 배열의 크기를 맞춰준다.
마지막으로 arr5 처럼 특정 인덱스에 값을 지정해줄 수도 있다.
0번 인덱스에는 10, 2번 인덱스에는 -10, 4번 인덱스에는 99 를 넣는다는 뜻이 되며, 나머지 인덱스들에는 기본값을 할당해줌으로써 [10, 0, -10, 0, 99] 와 같이 생성된다.
두 배열의 크기와 타입이 같을 경우에는 원소값들을 복사할 수 있다.
배열은 실제로 메모리 공간 상에서 지정된 크기만큼의 연속된 공간들을 할당받아서 그 안에 값을 유지하고 있는 것이기 때문에, 크기가 같은 두 배열은 서로 다른 메모리 상에서 같은 크기만큼 공간을 가지고 있다는 뜻이다.
아래처럼 같은 크기의 배열을 만든 뒤 복사하면 메모리 공간 전체의 값을 가져다가 씌워버리는 것이기 때문에, 사실상 deep copy가 일어난다.
func main() {
arr1 := [5]int{1, 2, 3, 4, 5}
arr2 := [...]int{10, 20, 30, 40, 50}
fmt.Println("arr1:", arr1)
fmt.Println("arr2:", arr2)
arr1 = arr2
arr1[0] = -1
fmt.Println("arr1 <- arr2")
fmt.Println("arr1:", arr1)
fmt.Println("arr2:", arr2)
}
$ go run test.go
arr1: [1 2 3 4 5]
arr2: [10 20 30 40 50]
arr1 <- arr2
arr1: [-1 20 30 40 50]
arr2: [10 20 30 40 50]
Go에서는 타입 검사를 강하게 하기 때문에, 모든 연산자에서 각각의 타입은 반드시 동일해야 한다.
그렇기 때문에 배열을 복사할때는 크기 뿐만 아니라 두 배열의 타입 역시 동일해야 한다.
n차원 배열은 그냥 배열과 사실 동일한 개념이다.
2차원 배열은 배열
을 타입으로 갖는 배열이고, 3차원 배열은 2차원 배열
을 타입으로 갖는 배열일 뿐이다.
그렇기 때문에 일반 배열과 같이, n-1 차원 배열이라는 원소들을 배열의 크기만큼 메모리에 가지고 있다.
예를 들어 2차원 배열의 경우는 아래처럼 사용하는데,
func main() {
var arr2d [3][4]int = [3][4]int{
{1, 2, 3, 4},
{3, 4, 5, 6},
{5, 6, 7, 8}, // 닫는 중괄호가 다른 줄에 위치할 경우 쉼표 필요!
}
for _, row := range arr2d {
for _, v := range row {
fmt.Print(v, " ")
}
fmt.Println()
}
}
$ go run test.go
1 2 3 4
3 4 5 6
5 6 7 8
arr2d 의 경우는 “길이가 4인 배열”을 하나의 원소로 가지며 그걸 3개 갖는 배열이기 때문에, 메모리에는 사실상 [int 4개] [int 4개] [int 4개] 의 공간을 차지하ㅑ는 것이다.
배열을 초기화하면서 위처럼 줄바꿈이 들어가는 경우에는, 닫는 중괄호가 같은 라인에 위치하지 않을 경우에는 반드시 ,
를 넣어줘야 한다.
예를 들어 마지막에 {5, 6, 7, 8} 뒤에 쉼표를 찍지 않으면 에러가 발생하는데, 이는 항목이 늘어날 경우 발생할 수 있는 실수들에 대비해 만들어놓은 규칙이다.