🔥 타입 단언

401자
5분

Go 언어에서는 인터페이스 값이 어떤 구체적인 타입의 값을 갖고 있는지 확인하고 접근할 수 있는 방법으로 타입 단언(type assertion)을 제공합니다. 타입 단언을 사용하면 인터페이스 값이 실제로 어떤 타입인지 알아낼 수 있죠.

t := i.(T)
 
go

위와 같은 문법으로 타입 단언을 사용할 수 있어요. 여기서 i는 인터페이스 값이고, T는 구체적인 타입입니다. 이 문장은 인터페이스 값 iT 타입의 값을 갖고 있다고 단언하며, 실제로 iT 타입의 값을 가지고 있으면 그 값을 t에 할당하게 됩니다.

만약 iT 타입의 값을 갖고 있지 않다면, 이 문장은 패닉(panic)을 발생시키게 됩니다. 따라서 타입 단언을 사용할 때는 주의해야 해요.

그렇다면 인터페이스 값이 특정 타입을 갖고 있는지 테스트하려면 어떻게 해야 할까요? 타입 단언은 두 개의 값을 반환할 수 있습니다. 첫 번째 값은 기본 값이고, 두 번째 값은 타입 단언이 성공했는지 여부를 나타내는 불리언 값이에요.

t, ok := i.(T)
 
go

위와 같이 사용하면, 인터페이스 값 iT 타입의 값을 갖고 있으면 t에는 기본 값이 할당되고 ok에는 true가 할당됩니다. 반면에 iT 타입의 값을 갖고 있지 않으면 ok에는 false가 할당되고 t에는 T 타입의 제로 값이 할당되며, 패닉은 발생하지 않아요.

이 문법이 맵에서 값을 읽어올 때의 문법과 유사하다는 점에 주목할 필요가 있습니다.

아래는 타입 단언을 사용하는 예제 코드입니다.

package main
 
import "fmt"
 
func main() {
	var i interface{} = "hello"
 
	// 타입 단언을 사용하여 인터페이스 값의 실제 타입에 접근
	s := i.(string)
	fmt.Println(s)  // 출력: hello
 
	// 타입 단언의 성공 여부를 확인
	s, ok := i.(string)
	fmt.Println(s, ok)  // 출력: hello true
 
	// 타입 단언이 실패하는 경우
	f, ok := i.(float64)
	fmt.Println(f, ok)  // 출력: 0 false
 
	// 타입 단언이 실패하면 패닉 발생
	f = i.(float64)  // panic: interface conversion: interface {} is string, not float64
	fmt.Println(f)
}
 
go

위 코드에서는 다양한 타입 단언의 사용 예시를 보여줍니다.

  1. i"hello"라는 문자열 값을 갖는 인터페이스 변수입니다.
  2. s := i.(string)istring 타입임을 단언하고, 그 값을 s에 할당합니다.
  3. s, ok := i.(string)은 타입 단언의 성공 여부를 확인하고, 성공하면 s에 값을 할당하고 oktrue를 할당합니다.
  4. f, ok := i.(float64)ifloat64 타입이 아니므로 타입 단언이 실패하고, f에는 float64의 제로 값인 0이 할당되고 ok에는 false가 할당됩니다.
  5. f = i.(float64)는 타입 단언이 실패하므로 패닉이 발생합니다.

이렇게 타입 단언을 사용하면 인터페이스 값의 실제 타입을 확인하고 접근할 수 있습니다. 하지만 타입 단언을 사용할 때는 주의를 기울여야 합니다. 만약 타입 단언이 실패하면 패닉이 발생할 수 있기 때문이죠. 따라서 타입 단언을 사용하기 전에 인터페이스 값의 실제 타입을 잘 파악하고, 필요한 경우 두 번째 반환값을 활용하여 타입 단언의 성공 여부를 확인하는 것이 좋습니다.