배열이란 연속되서 붙어있는 자료구조를 의미한다. 같은 타입의 자료를 묶어줄때 사용하는 것이 배열인 것이다.
배열은 여러가지 특징을 지니지만 이번 시간에 배열을 자료구조적인 관점에서 설명하지 않겠다.
그냥 배열은 특정자료형을 한개가 아닌, 여러개를 묶어다니기 위해서 만든 것이다 정도로만 알면되겠다.
만약 자세한 설명이 필요하다면 이 곳을 참조하라.
이 블로그에서는 Go에서 배열과 슬라이스를 어떻게 생성하는지, 그리고 Go에서 배열과 슬라이스에 대한 특징을 다루도록 하겠다.
배열(Array)
package main
import "fmt"
func main() {
arr1 := [5]int{1, 2, 3, 4, 5}
arr2 := [...]int{2, 4, 6, 8, 10}
for i := 0; i < len(arr1); i++ {
fmt.Print("arr1[", i, "] = ", arr1[i], "\n")
}
fmt.Println()
for index, value := range arr2 {
fmt.Print("arr2[", index, "] = ", value, "\n")
}
}
코드에서 새로운 개념들이 많이 등장하므로 하나하나 설명하면서 넘어가겠다.
arr1 := [5]int{1, 2, 3, 4, 5}
arr2 := [...]int{2, 4, 6, 8, 10}
배열의 선언은 위처럼 한다.
arr := [<인덱스 넘버>]int{<값들>} - 1
arr := [...]int{<값들>} - 2
위의 방식은 배열의 크기를 명시적으로 정한 것이다. 여기서는 5로 정했다.
아래의 경우는 명시적으로 정한것은 아니다. 그래서 뒤에 값들의 수에 맞게 정해진다.
여기서는 원소가 5개이므로 5개가된다.
len(arr1)
배열의 길이는 항상 언제든지 확인할 수 있다.
이때는 len함수를 사용하면된다.
arr1[i]
배열의 원소에 접근하는 방법은 해당 번호를 배열에 적는 것이다.
여기서 중요한건 배열의 크기를 5로 정할경우 배열의 원소 번호는 0번부터 배정된다는 것이다.
R같은 특수한 언어를 제외하고 대부분 언어들은 인덱스가 0번부터이므로 5로 지정하면 마지막 번호는 4가된다.
for i := 0; i < len(arr1); i++ {
fmt.Print("arr1[", i, "] = ", arr1[i], "\n")
}
만약 배열에 순서대로 접근하고 싶으면 for문을 써서 접근하는 방법이 있다.
단 전통적인 방법 보다는 아래와 같은 방법을 더 많이 쓴다.
for index, value := range arr2 {
fmt.Print("arr2[", index, "] = ", value, "\n")
}
이렇게 range구문을 사용하면 for each 구문으로 돌아간다.
이때 index와 value를 뱉어내는데(변수의 이름은 뭐든 상관없다.)
index는 지금 몇번인지, 그리고 value는 값을 뱉어낸다.
만약 index번호를 쓰고싶지 않다면 _를 사용한다.
for _, value := range arr2 {
fmt.Println(value)
}
위처럼 사용하면 된다.
_는 변수를 포기하겠다는 뜻이다.
그러면 index를 포기하므로 루프를 돌릴 수 있다.
배열은 굉장히 유용하지만....
아쉽게도 Go에서는 한정된 역활로만 사용 된다.
그 이유는 java에서 배열에 죽고 ArrayList만 주구장창 쓰는 이유와 동일하다.
바로 아래의 slice녀석 때문이다.
슬라이스(slice)
package main
import "fmt"
func main() {
var arr1 = [5]int{1, 2, 3, 4, 5}
arr1 = append(arr1, 6)
for _, value := range arr1 {
fmt.Print(value)
}
}
배열에 원소를 추가하는 함수가 append라는 함수이다.
그러면 append함수로 배열의 원소를 추가하면되겠네!! 라고 생각한다면 큰 오산인다.
한번 실행해보라.
보다시피 불가능 하다고 뜬다. 그리고 첫번째 인자로 슬라이스를 넣으라고 한다.
그렇다. 배열은 크기를 늘릴 수 없지만 슬라이스는 가능하다.
그래서 Go에서는 실제로 슬라이스를 많이 사용한다.
아래의 슬라이스를 쓴 예시를 보도록 하자.
package main
import "fmt"
func main() {
var arr1 = []int{1, 2, 3, 4, 5}
arr1 = append(arr1, 6)
for _, value := range arr1 {
fmt.Print(value)
}
}
뭔가 바뀐것이 느껴지는가?
모르겠다고? 다시 자세히 보여드리도록 하겠다.
var arr1 = [5]int{1, 2, 3, 4, 5}
이게 배열이다.
아래를 보도록 하자.
var arr1 = []int{1, 2, 3, 4, 5}
이게 슬라이스이다.
뚜렷한 차이라면 원소에 값을 지정하지 않는 다는 것이다.
슬라이스는 가변배열, 동적배열이다.
즉 값의 크기를 늘릴수 있거나 줄일 수 있다는 것이다.
그럼 아래의 소스를 보자.
package main
import "fmt"
func main() {
var arr1 = []int{1, 2, 3, 4, 5}
arr1 = append(arr1, 6)
for _, value := range arr1 {
fmt.Print(value)
}
}
위의 코드가 과연 작동할까? 라고 묻는 다면 답은 yes이다.
한번 실행해보자.
이렇게 값을 추가할 수 있다.
이러한 특징 때문에 슬라이스는 빈 슬라이스 역시가능하다.
초기값을 지정하지 않는 것이다.
package main
import "fmt"
func main() {
var arr1 = []int{}
arr1 = append(arr1, 1)
arr1 = append(arr1, 2)
arr1 = append(arr1, 3)
for _, value := range arr1 {
fmt.Print(value)
}
}
슬라이스에 값을 넣지않으면 빈 슬라이스가된다.
이 경우 값을 넣어주면된다.
제대로 동작하는지 확인해보자.
또한 슬라이스의 값을 초기화하는 방법이 있다.
일괄적인 값을 쓰는 방법이다.
package main
import "fmt"
func main() {
var arr1 = make([]int, 5)
for _, value := range arr1 {
fmt.Print(value)
}
}
make함수를 사용해서 슬라이스를 초기화 시킬 수 있다.
이때 뒤의 숫자는 일단 슬라이스의 크기를 의미한다.
make함수로 초기화 하면 기본적으로 0으로 초기화된다.
슬라이싱
package main
import "fmt"
func main() {
arr1 := []int{1, 2, 3, 4, 5, 6}
arr1_1 := arr1[:3]
arr1_2 := arr1[3:]
arr1_3 := arr1[2:5]
for _, value := range arr1_1 {
fmt.Print(value)
}
fmt.Println()
for _, value := range arr1_2 {
fmt.Print(value)
}
fmt.Println()
for _, value := range arr1_3 {
fmt.Print(value)
}
}
배열이나 슬라이스는 짤라낼수 있다. 이를 슬라이싱이라고 부른다.
위는 슬라이싱을 사용한 예제이다.
arr1_1 := arr1[:3]
앞에 적지 않는다면 이는 0번 인덱스를 의미한다. 그리고 뒤에 3이라고 적으면 3번직전인 2번까지 잘라낸다.
arr1_2 := arr1[3:]
이 경우 3번부터 시작해서 마지막 까지 잘라낸다.
arr1_3 := arr1[2:5]
이 경우는 2 번부터 4번까지 잘라낸다.
'Programming > Go' 카테고리의 다른 글
[Go-10]함수(function) (0) | 2018.09.01 |
---|---|
[Go-09]맵(Map) (0) | 2018.08.31 |
[Go-07]반복문 (0) | 2018.08.31 |
[Go-06]switch(스위치) (0) | 2018.08.31 |
[Go-05]조건문 (0) | 2018.08.31 |