배열
- 배열은 같은 타임으로 이루어인 연속된 메모리 공간입니다.
- 배열을 이루고 있는 값은 요소(element)라고 부르고, 요소를 가리키는 위치 값을 인덱스(index) 라고 부릅니다.
var 변수명 [요소 개수]타입
package main import "fmt" func main() { var singer [3]string = [3]string {"aespa", "blackPink", "BTS"} for i := 0; i < 3; i++ { fmt.Println(singer[i]) } }
- 배열의 인덱스는 0부터 시작합니다.
- 마지막 요소의 위치는 (요소 개수 – 1) 입니다.
- 혼란을 방지하기위해 for문으로 배열을 순회할 때에는 무조건 0부터 시작하고, 조건은 “배열의 개수보다 작으면” 으로 하면 좋습니다.
배열 선언시 주의해야 할 점
배열을 선언할때 실수를 방지하기 위해서 배열의 개수를 변수로 지정하면 좋습니다. 이때 배열의 개수를 지정하는 값은 반드시 “상수” 이어야 합니다.
다음은 에러가 발생하는 코드입니다.
package main import "fmt" func main() { n := 3 var singer [n]string = [n]string{"aespa", "blackPink", "BTS"} for i := 0; i < n; i++ { fmt.Println(singer[i]) } }
“n := 3” 이 구문은 변수를 선언하는 구문이기때문에 값의 변경이 가능합니다. 그래서 값을 변경할 수 없는 배열의 개수로 넣으면 에러가 납니다. 따라서, 아래 소스코드와 같이 상수로 선언을 하면 잘 돌아갑니다.
package main import "fmt" func main() { const n int = 3 var singer [n]string = [n]string{"aespa", "blackPink", "BTS"} for i := 0; i < n; i++ { fmt.Println(singer[i]) } }
다음은 배열의 길이를 지정하지 않고, 초기화 시킨 배열 요소의 개수로 길이를 정하는 방법입니다.
package main import "fmt" func main() { singer := [...]string{"aespa", "blackPink", "BTS"} // "..."은 생략 가능 for i := 0; i < len(singer); i++ { fmt.Println(singer[i]) } }
배열의 순회
for 문에서 인덱스 접근을 이용한 배열의 순회는 실수할 확률이 높습니다. 인덱스 범위를 신경쓰지 않고 배열을 순회하려면 아래와 같은 range를 이용하여 for문을 작성하시면 됩니다.
package main import "fmt" func main() { singer := [...]string{"aespa", "blackPink", "BTS"} // "..."은 생략 가능 for i, v := range singer { fmt.Println(i, v) } }
i는 index라는 뜻이고, v는 value라는 뜻입니다. 만약 index를 사용하지 않는다면 아래와 같이 i를 _로 처리합니다.
package main import "fmt" func main() { singer := [...]string{"aespa", "blackPink", "BTS"} // "..."은 생략 가능 for _, v := range singer { fmt.Println(v) } }
사용하지 않는 변수를 만들어두는 것은 코드 가독성에도 좋지 않고, 실수할 가능성이 높으니 사용하지 않는 변수는 없애주는 습관을 들이면 좋습니다.
다차원 배열
수학에서 x축, y축, z축이 있듯이 선형적인 자료구조인 배열을 이용하면 차원을 표현할 수 있습니다. 먼저 2차원 배열을 만들어 보겠습니다.
var a = [5]int{1, 2, 3, 4, 5} // 1차원 배열 var b = [2][5]int{ // b배열을 초기화 {1, 2, 3, 4, 5}, // b[0] 초기화 {6, 7, 8, 9, 10}, // b[1] 초기화 } var c = [2][5][2]int{ // b배열을 초기화 { // b[0] 초기화 {1, 0}, // b[0][0][0] b[0][0][1] 초기화 {1, 1}, // b[0][1][0] b[0][1][1] 초기화 {1, 2}, // b[0][2][0] b[0][2][1] 초기화 {1, 3}, // b[0][3][0] b[0][3][1] 초기화 {1, 4}, // b[0][4][0] b[0][4][1] 초기화 }, { // b[1] 초기화 {2, 0}, // b[1][0][0] b[1][0][1] 초기화 {2, 1}, // b[1][1][0] b[1][1][1] 초기화 {2, 2}, // b[1][2][0] b[1][2][1] 초기화 {2, 3}, // b[1][3][0] b[1][3][1] 초기화 {2, 4}, // b[1][4][0] b[1][4][1] 초기화 }, }
보시는 바와 같이 3차원 배열부터는 이해하기가 쉽지 않습니다. 따라서 보통은 2차원 배열까지만 사용합니다. 만약 3차원 배열이 필요한 경우라면 좀 더 쉬운 방법은 없는지 고민해보는 것이 좋습니다.
다차원 배열의 순회
for문을 이용해서 다차원 배열을 순회해 보겠습니다.
package main import "fmt" func main() { var a = [5]int{1, 2, 3, 4, 5} // 1차원 배열 var b = [2][5]int{ // b배열을 초기화 {1, 2, 3, 4, 5}, // b[0] 초기화 {6, 7, 8, 9, 10}, // b[1] 초기화 } var c = [2][5][2]int{ // b배열을 초기화 { // b[0] 초기화 {1, 0}, // b[0][0][0] b[0][0][1] 초기화 {1, 1}, // b[0][1][0] b[0][1][1] 초기화 {1, 2}, // b[0][2][0] b[0][2][1] 초기화 {1, 3}, // b[0][3][0] b[0][3][1] 초기화 {1, 4}, // b[0][4][0] b[0][4][1] 초기화 }, { // b[1] 초기화 {2, 0}, // b[1][0][0] b[1][0][1] 초기화 {2, 1}, // b[1][1][0] b[1][1][1] 초기화 {2, 2}, // b[1][2][0] b[1][2][1] 초기화 {2, 3}, // b[1][3][0] b[1][3][1] 초기화 {2, 4}, // b[1][4][0] b[1][4][1] 초기화 }, } for _, v := range a { fmt.Print(v, " ") } fmt.Println() fmt.Println() for _, arr := range b { for _, v := range arr { fmt.Print(v, " ") } fmt.Println() } fmt.Println() for _, arr1 := range c { for _, arr2 := range arr1 { for _, v := range arr2 { fmt.Print(v, " ") } fmt.Print("\t") } fmt.Println() } fmt.Println() }
Tucker의 Go 언어 프로그래밍 참조.
책을 보면서 공부한 내용을 정리하면서 작성하는 글입니다. 따라서, 주제 하나를 많은 시간을 들여서 쓰지 않고, 간단하게 작성하는 것부터 시작해서, 계속 다듬어가면서 업데이트해 나갈 생각입니다. 참고하는 자료가 있을 때마다 출처를 적어 놓겠습니다.