명시적이지 않은 듯 명시적인 Go

그것의 타입을 Go는 알고 있다.

변수에서 살펴 본 것처럼 Go는 변수를 선언할 때 초기값을 같이 입력하면 굳이 타입을 명시하지 않아도 된다.

var i = 1
f := 3.14
c := 1.0 + 1.0i

그렇다면 이 경우 i, f, c의 타입은 각각 어떻게 될까?

Go에서 변수의 타입을 확인하기 위해서는 reflect 패키지를 활용할 수 있다.

package main

import "fmt"
import "reflect"

func main() {
	var i = 1
	f := 3.14
	c := 1.0 + 1.0i
	
	fmt.Println(i, reflect.TypeOf(i))
	fmt.Println(f, reflect.TypeOf(f))
	fmt.Println(c, reflect.TypeOf(c))
}

위 코드의 실행 결과는 다음과 같다.

1 int
3.14 float64
(1+1i) complex128

결과에서 확인할 수 있는 것처럼 Go는 타입을 명시하지 않을 경우 실수에 대해서는 float64를, 복소수에 대해서는 complex128을 기본 타입으로 한다. 즉, 해당 값을 표시할 수 있는 가장 큰—가장 공간이 넓은— 타입을 선택하는데 정수에 대해서만은 int64가 아닌 int를 기본 타입으로 한다.

그럼 타입을 명시하지 않고 선언한 변수에 다른 타입을 재할당하면 어떻게 될까?

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package main

import "fmt"
import "reflect"

func main() {
	var i = 1
	f := 3.14
	c := 1.0 + 1.0i
	
	fmt.Println(i, reflect.TypeOf(i))
	fmt.Println(f, reflect.TypeOf(f))
	fmt.Println(c, reflect.TypeOf(c))
	
	var f1 float32 = 3.14
	f = f1
}

위 코드는 다음과 같은 오류가 발생한다.

./main.go:16:5: cannot use f1 (type float32) as type float64 in assignment

코드 상으로는 타입을 명시하지 않았지만 초기값을 넣으면서 이미 해당 변수는 float64라는 하나의 타입으로 고정된 것이다.

암시적 변환(implicit conversion)을 지원하는 다른 언어 개발자들의 불만이 들린다.

float32float64에 넣겠다는데, 이정도는 자동으로 해줘야 하는거 아니야?

하지만 Go는 모든 형변환(type conversion)에 대해 명시적인 명령을 강제한다.

Go의 형변환 방법은 다음과 같다.

T(v)

눈 크게 뜨고 보시라. 괄호가 저기가 아니고 여기다. 함수처럼 사용한다.