소개
현대 소프트웨어 개발에서 우리는 종종 방대한 양의 데이터를 저장해야 합니다.
우리가 배운 것을 바탕으로, 우리는 쉽게 수많은 변수를 정의할 수 있습니다.
하지만, 회사의 직원 이름을 기록하기 위해 변수를 사용해야 하고, 데이터 규모가 수백 또는 수천에 달한다면, 일일이 변수를 정의해야 할까요?
물론 아닙니다. 유사한 속성을 가진 데이터의 경우, 배열 (array) 을 사용하여 정의하고 저장할 수 있습니다.
배열을 기차처럼 함께 모인 변수들의 집합이라고 생각할 수 있습니다. 특정 변수를 찾고 싶을 때는 기차 번호 (배열 이름) 와 좌석 번호 (인덱스) 만 알면 됩니다. 그러면 변수 이름을 몰라도 해당 변수를 찾고 조작할 수 있습니다.
이 섹션에서는 배열의 다양한 기본 연산에 대해 배우겠습니다.
지식 포인트:
- 배열 정의 (Array definition)
- 배열 초기화 (Array initialization)
- 배열 순회 (Array traversal)
- 배열 요소의 특징 (Characteristics of array elements)
배열 정의 (Array Definition)
배열은 어떻게 정의할까요?
변수에 대해 배웠던 상황을 떠올려 봅시다. int 변수를 어떻게 정의했었나요?
var a int
즉, 다음과 같습니다:
var variable_name variable_type
마찬가지로, int 배열은 다음과 같이 정의할 수 있습니다:
var a [10]int
즉, 다음과 같습니다:
var variable_name [number_of_elements]variable_type
이 방식으로, 우리는 용량이 10 인 기본 int 배열 a를 정의했습니다.
초기화 리스트 (Initialization List)
배열을 정의하는 방법을 이해했으니, 이제 배열을 초기화하는 방법을 배워보겠습니다.
배열을 초기화할 때, 초기화 목록 (initialization list) 을 사용하여 배열 요소의 초기 값을 설정할 수 있습니다.
~/project 디렉토리에 array.go 파일을 생성합니다:
cd ~/project
touch array.go
array.go에 다음 코드를 작성합니다:
package main
import "fmt"
func main() {
// Automatically initialized to the zero value of the element type
var simpleArray [3]int
// Initialize with specified initial values, and use the zero value to fill in the missing elements
var numArray = [3]int{1, 2}
// Initialize with specified initial values
var cityArray = [2]string{"London", "Chengdu"}
fmt.Println(simpleArray) // [0 0 0]
fmt.Println(numArray) // [1 2 0]
fmt.Println(cityArray) // [London Chengdu]
}
코드를 실행합니다:
go run ~/project/array.go
예상 출력:
[0 0 0]
[1 2 0]
[London Chengdu]
위 코드는 초기화 목록을 사용하여 초기 값을 지정하는 세 가지 방법을 보여줍니다:
- 목록을 전달하지 않음: 요소 타입의 제로 값으로 초기화
- 부분 목록 전달: 지정된 요소는 지정된 값으로 초기화하고, 나머지 요소는 제로 값으로 초기화
- 전체 목록 전달: 지정된 값으로 초기화
전달된 목록의 길이가 배열의 요소 수보다 크면 코드가 컴파일되지 않음에 유의하십시오.
길이 추론 초기화 (Inferred Length Initialization)
초기화 목록을 사용하여 배열을 초기화할 때, 제공된 초기 값의 수가 요소의 수보다 작거나 같도록 해야 합니다.
일반적으로, 초기 값을 기반으로 컴파일러가 배열 길이를 추론하도록 할 수 있습니다.
array.go 파일을 다음과 같이 수정합니다:
package main
import "fmt"
func main() {
var simpleArray [3]int
var numArray = [...]int{1, 2}
var cityArray = [...]string{"London", "Chengdu"}
fmt.Println(simpleArray) // [0 0 0]
fmt.Println(numArray) // [1 2]
fmt.Printf("The type of numArray is: %T\n", numArray) // The type of numArray is: [2]int
fmt.Println(cityArray) // [London Chengdu]
fmt.Printf("The type of cityArray is: %T\n", cityArray) // The type of cityArray is: [2]string
}
코드를 실행합니다:
go run ~/project/array.go
예상 출력:
[0 0 0]
[1 2]
The type of numArray is: [2]int
[London Chengdu]
The type of cityArray is: [2]string
인덱스 지정 초기화 (Initialization with Specified Indices)
때로는 초기화 목록을 사용하든 길이를 추론하든 관계없이 배열의 특정 위치에 특정 초기 값을 할당하고 싶을 수 있습니다.
array.go 파일을 다음과 같이 수정합니다:
package main
import "fmt"
func main() {
a := [...]int{1: 1, 3: 5}
fmt.Println(a) // [0 1 0 5]
fmt.Printf("The type of array a is: %T\n", a) // The type of array a is: [4]int
}
코드를 실행합니다:
go run ~/project/array.go
예상 출력:
[0 1 0 5]
The type of array a is: [4]int
위 코드는 인덱스 1 과 3 의 요소의 초기 값을 각각 1 과 5 로 지정합니다. 또한 길이 추론 초기화 방법을 사용하는데, 이는 학습해야 합니다.
참고: 컴퓨팅에서 인덱스는 0 부터 시작합니다.
배열 순회 (Array Traversal)
때로는 배열의 각 요소에 접근하여 하나씩 연산을 수행해야 할 필요가 있습니다.
여기서는 배열을 순회하는 두 가지 방법을 소개합니다:
array.go에 다음 코드를 작성합니다:
package main
import "fmt"
func main() {
a := [...]int{123, 321, 456, 777}
// Method 1: range
fmt.Println("Traversing the array using range")
for index, value := range a {
fmt.Println(index, " ", value)
}
// Method 2: using indices
fmt.Println("\nTraversing the array using indices")
for i := 0; i < len(a); i++ {
fmt.Println(a[i])
}
}
코드를 실행합니다:
go run ~/project/array.go
예상 출력:
Traversing the array using range
0 123
1 321
2 456
3 777
Traversing the array using indices
123
321
456
777
위의 두 가지 방법 모두 전체 배열을 순회하는 데 사용할 수 있습니다.
배열 요소 접근 (Accessing Array Elements)
배열의 특정 요소, 즉 변수에 접근하려면 인덱스를 사용합니다.
대부분의 프로그래밍 언어와 마찬가지로 배열의 인덱스는 0 부터 시작하며, 마지막 요소의 인덱스는 len-1입니다.
이 한계를 초과하는 인덱스가 코드에서 사용되면 범위 초과 오류가 발생합니다.
a 배열의 i번째 요소에 접근하려면 다음 표기법을 사용할 수 있습니다:
a[i]
즉:
array_name[index_of_element]
배열의 값 타입 (Value Type of Arrays)
배열은 값 타입입니다. 배열을 할당하거나 배열을 매개변수로 전달하면 전체 배열이 복사됩니다. 즉, 원본 배열이 아닌 복사본의 값을 수정하게 됩니다.
array.go에 다음 코드를 작성합니다:
package main
import "fmt"
func modifyArray(x [3]int) {
x[0] = 100
}
func main() {
a := [3]int{10, 20, 30}
modifyArray(a) // The variable `x` in `modifyArray` is a copy of `a`
fmt.Println(a) // [10 20 30]
}
코드를 실행합니다:
go run ~/project/array.go
출력 결과는 다음과 같습니다:
[10 20 30]
위의 코드에서 a 배열이 modifyArray 함수에 전달될 때, 실제로 원본 배열의 복사본만 전달되는 것을 볼 수 있습니다.
함수 내에서 배열 x의 값을 변경해도 원본 배열 a에는 영향을 미치지 않습니다.
요약
이번 랩에서는 다음을 배웠습니다:
- 배열을 정의하는 방법
- 배열 초기화의 세 가지 방법
- 배열의 특징과 요소에 접근하는 방법
배열은 실제 개발에서 일반적으로 사용되지는 않지만, Go 에서 일반적으로 사용되는 자료 구조를 배우기 위한 기초입니다.
모든 Gopher 들이 부지런히 연습하고 배운 내용을 적용할 수 있기를 바랍니다.



