Go를 배워보자 6일차 - 배열

0

Go

목록 보기
6/12

GO에서의 배열

1. 배열 선언

지난번 포인터 변수를 선언했을 때 재밌었던 것은 변수의 타입 앞에 *(에스테리스크)를 썼다는 것이다.

var pIntValue *int;

배열 역시도 마찬가지이다. 결국 배열의 사이즈를 나타내는 []을 변수 타입 앞에 써주기만 해주면 되는 것이다.

var 배열이름 [사이즈]타입

다음과 같이 선언해주면 되는 것이다.

그럼 사용방법을 한번 보도록 하자

package main

import "fmt"

func main() {
	var array [10]string
	array[0] = "hello"
	array[1] = "world"

	fmt.Println(array[0]) // hello
	fmt.Println(array[1]) // world
}

2. 배열 리터럴

배열이 가질 값을 미리 알고 있을 경우에는 배열 리터럴을 사용하여 배열을 초기화할 수 있다.

이 때 배열 리터럴을 사용하게되면 단축 변수 선언이 가능해진다.

var 배열이름 [사이즈]타입 = [사이즈]타입{,,, ...}

다음과 같은 형식을 이용한다. 배열 리터럴은 해당 값이 배열이라는 표시를 해주기 위해서 {} 말고도 [사이즈]타입 을 써주어야 한다.

까다로워보이지만, 배열 리터럴에도 사이즈를 정해줄 수 있다는 장점이 있다.

package main

import "fmt"

func main() {
	var array [10]string = [10]string{"hello", "world"}
	counts := [10]int{1, 2, 3, 4, 5, 6, 7} // 단축 변수 선언
	fmt.Println(array[0]) // hello
	fmt.Println(array[1]) // world
	fmt.Println(counts[0]) // 1
	fmt.Println(counts[5]) // 6
}

다음과 같이 배열 리터럴을 사용하여 선언과 동시에 값을 초기화할 수도 있고 단축 변수 선언을 통해 값을 바로 할당해줄수도 있다.

재밌는 것은 fmt.Println()에 배열 값을 넣으면 전체를 출력해준다.

package main

import "fmt"

func main() {
	var array [10]string = [10]string{"hello", "world"}
	counts := [10]int{1, 2, 3, 4, 5, 6, 7}
	fmt.Println(array) // [hello world        ]
	fmt.Println(counts) [1 2 3 4 5 6 7 0 0 0]
}

배열의 빈 값들은 '제로값'으로 채워진다. 즉 default 값인데, string은 "" 이고, 정수인 int는 0이다.

3. 루프로 배열 접근하기

  • 인덱스로 접근하기
    가장 단순한 방법이다.

만약 배열의 사이즈를 모를 경우에는 len이라는 내장 함수를 사용하면 된다.

package main

import "fmt"

func main() {
	var array [10]string = [10]string{"hello", "world"}
	counts := [10]int{1, 2, 3, 4, 5, 6, 7}
	for i := 0; i < 10; i++ {
		fmt.Print(array[i]) // helloworld
	}
	fmt.Print("\n")
	for i := 0; i < len(counts); i++ {
		fmt.Print(counts[i]) // 1234567000
	}

}

다음과 같이 사이즈를 알면 사이즈 값을 for문의 조건문에 써주어도 되고, 모른다면 len()이라는 내장함수를 이용하여 for문의 조건문에 써주면 된다.

  • for ... range를 이용한 방법

range는 키워드이지 함수가 아니다. 즉, range(배열) 이 아니라 var, const처럼 range 배열로 사용한다.

range는 배열의 인덱스와 값을 하나하나 빼내어 변수에 할당해주는 기능을 한다.

이를 이용하여 배열 순회를 해보도록 하자

package main

import "fmt"

func main() {
	var array [10]string = [10]string{"hello", "world", "my", "name", "is", "hell"}
	for index, value := range array {
		fmt.Println(index, value)
	}
}

결과는 다음과 같다.

0 hello
1 world
2 my
3 name
4 is
5 hell
6
7
8
9

for ... range를 사용하면 가장 좋은 것은 index를 통해 직접 배열에 접근하지 않아도 된다는 것이다. 즉, 배열의 사이즈를 통해 배열을 접근하는 방법은 segmentation error를 발생할 문제가 있기 때문에 위험하다.

그러나 range는 자동으로 index, value를 가져오므로 보다 안전하다.

그럼 만약, value만 꺼내오고 싶거나, index만 꺼내오고 싶을 땐 어떻게 해야할까??

아주 간단한데, '빈 식별자( _ )'를 사용하기만 하면 된다.

package main

import "fmt"

func main() {
	var array [10]string = [10]string{"hello", "world", "my", "name", "is", "hell"}
	for i, _ := range array {
		fmt.Println(i)
	}
	for _, value := range array {
		fmt.Println(value)
	}
}

결과는 다음과 같다.

0
1
2
3
4
5
6
7
8
9
hello
world
my
name
is
hell

그러나, 한가지 착각하지 말아야할 것은 해당 사이즈를 넘어서 값을 추가하는 것은 불가능하다.

즉, 인덱스로 값을 변경하는 것은 가능하지만, 동적 배열이나 리스트처럼 값을 추가하는 것은 불가능하다.

배열은 정적 배열로서 처음 할당받은 사이즈에서 벗어나질 않는 것이다.

그렇다면 go에서는 동적으로 원소를 추가하고 사이즈가 바뀌는 자료구조가 없는 것일까?? 아니다. 이는 슬라이스라는 자료 구조로 해결 가능하며 다음 시간에 배우도록 하자

0개의 댓글