갈루아의 반서재

Go 에서 array 는 다음과 같이 표현된다. 

1
var x [5]int
cs

x 는 5개의 int 로 구성된 array 이다. 다음의 코드를 실행해보자.

1
2
3
4
5
6
7
8
9
package main
 
import "fmt"
 
func main() {
  var x [5]int
  x[4= 100
  fmt.Println(x)
}
cs

실행결과는 다음과 같다.

1
2
3
~/go/src/golang-book/chapter6# go run main.go
[0 0 0 0 100]
 
cs

x[4] = 100의 의미는 “array x 의 5번째 원소의 값을 100 으로 셋팅하라” 는 것이다. x[4] 가 5번째 원소를 나타낸다는 사실이 이상해보일 수 있으나, array 는 0에서 시작하기 때문에 이상할 것은 없다. 

array 를 사용하는 다른 예를 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package main
 
import "fmt"
 
func main() {
  var x [5]float64
  x[0= 98
  x[1= 93
  x[2= 77
  x[3= 82
  x[4= 83
 
  var total float64 = 0
  for i := 0; i < 5; i++ {
    total += x[i]
  }
  fmt.Println(total / 5)
}
cs

이 프로그램은 테스트 점수의 평균을 산출해주는 것으로, 실행하면 아래와 같이 86.6이 출력된다. 

1
2
3
~/go/src/golang-book/chapter6# go run main.go
86.6
 
cs

로직을 다시 정리해보자.

먼저 테스트 점수를 담는 길이 5의 배열을 생성하고, 각각에 점수를 부여한다. 

그리고 총점을 계산하기 위해 루프를 만든다.

마지막으로 총점을 원소 갯수로 나눠서 평균을 구한다.


위의 코드를 좀 더 효율적으로 개선해보자. 먼저 원소의 갯수를 6개로 늘리고 아래와 같이 수정한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
 
import "fmt"
 
func main() {
  var x [6]float64
  x[0= 98
  x[1= 93
  x[2= 77
  x[3= 82
  x[4= 83
  x[5= 90
 
  var total float64 = 0
  for i := 0; i < len(x); i++ {
    total += x[i]
  }
  fmt.Println(total / len(x))
}
cs

실행하면 다음과 같은 에러가 발생한다.

1
2
3
4
~/go/src/golang-book/chapter6# go run main.go
# command-line-arguments
./main.go:18:21: invalid operation: total / len(x) (mismatched types float64 and int)
 
cs

상기 이슈는 len(x) 와 total 이 서로 다른 타입을 갖기 때문이다. total은 float64 인 반면, len(x) 은 int 이다. 그러므로 len(x) 를 float64 로 변환하자. 

1
fmt.Println(total / float64(len(x)))
cs

위는 타입 변환의 간단한 예이고, 일반적으로 타입명을 함수같이 사용한다.

루프문을 다음과 같이 고쳐보자. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
 
import "fmt"
 
func main() {
  var x [6]float64
  x[0= 98
  x[1= 93
  x[2= 77
  x[3= 82
  x[4= 83
  x[5= 90
 
  var total float64 = 0
  for i, value := range x {
    total += value
  }
  fmt.Println(total / float64(len(x)))
}
cs

상기 for loop 문에서 i 는 array 상의 현재 위치를 나타내고 그 값은 x[i] 와 같다. range 키워드 다음에 반복하고자하는 변수 이름이 나온다. 

하지만 실행을 해보면 다른 에러가 발생한다. 

1
2
3
~/go/src/golang-book/chapter6# go run main.go
# command-line-arguments
./main.go:15:7: i declared and not used
cs

Go 컴파일러는 사용한적이 없는 변수를 생성하는 것을 허용하지 않기 때문이다.  루프문 안의 i 를 다음과 같이 변경해야할 필요가 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package main
 
import "fmt"
 
func main() {
  var x [6]float64
  x[0= 98
  x[1= 93
  x[2= 77
  x[3= 82
  x[4= 83
  x[5= 90
 
  var total float64 = 0
  for _, value := range x {
    total += value
  }
  fmt.Println(total / float64(len(x)))
}
cs

단일 _ (underscore) 는 컴파일러로 하여금 필요없다는 것을 말해주기 위한 것이다(위의 경우에는 반복자 변수가 필요없다고 알리는 역할을 한다). 실행하면 다음과 같이 정상작동함을 알 수 있다.

1
2
3
~/go/src/golang-book/chapter6# go run main.go
87.16666666666667
 
cs

Go 는 array 를 생성하는 보다 간단한 구문도 제공한다. Go 는 타입을 추론할 수 있기 때문에 더 이상 타입을 지정할 필요가 없다. 

1
:= [5]float649893778283 } 
cs

또는 다음과 같이 작성해도 무방하다.

1
2
3
4
5
6
7
:= [5]float64{
  98,
  93,
  77,
  82,
  83,
}
cs

그리고 원소 앞에 주석처리를 함으로써 손쉽게 배열에서 해당 원소를 제거할 수 있다.

1
2
3
4
5
6
7
:= [4]float64{
  98,
  93,
  77,
  82,
  // 83,
}
cs