쿼카러버의 기술 블로그
[golang] Type assertion과 Type conversion 차이 본문
Type assertion과 Type conversion이 처음에 golang을 공부할때 많이 헷갈리는 개념 중 하나였다.
먼저 assert라는 단어의 사전적 정의를 보면, "사실임을 주장한다"이다.
conversion이 의미하는 "전환, 변환"이기 때문에 둘의 사전적 의미에도 많은 차이가 있다.
따라서 이 둘은 분명히 차이가 있는 개념이고, 이 둘에 대해 설명해보겠다.
type conversion
형 변환(type casting)이다. golang에서는 형변환을 하기 위해서는 아래와 같이 명시적으로 해주어야 한다.
var i int = 42
var f float64 = float64(i)
var u uint = uint(f)
C와는 다르게, 다른 타입의 변수에 값을 assign하기 위해서는 위처럼 명시적으로 형변환을 해주어야 한다.
위에 형변환을 위해 사용한 float64
나 uint
를 지우고 코드를 보면 컴파일 에러가 발생한다.
type assertion
앞서 말했듯이 type assertion은 전환, 변환을 의미하지 않는다. a tour of go에서의 type assertion의 의미를 아래와 같이 정의하고 있다.
A type assertion provides access to an interface value's underlying concrete value.
위 정의에 따르면 Type Assertion은 interface type의 value의 타입을 확인하는 것이다.
다른 의미로 설명하면 인터페이스가 가지고 있는 실제 값(concrete value)에 접근할 수 있게 해준다.
처음엔 무슨말인가 싶겠지만 아래 예시를 보면 이해하기 쉽다.
package main
func main() {
var a interface{} = 1
i := a // a와 i는 dynamic type이고 값은 1
j := a.(int) // j는 int 타입이고, 값은 1
println(i) // 포인터 주소 출력
println(j) // 1 출력
}
위 예시에서 보여지듯이 Type Assertion을 하기 위해서는
interface type의 x
와 타입 T
를 → x.(T)
로 포현했을때,
x
가 nil 이 아니며,x
는T
타입에 속한다는 점을
확인할 수 있다(assert 할 수 있다)
즉, 위와 같이 코드를 실행할 경우
x
가 nil 이거나x
의 타입이T
가 아니라면 → Runtime ERRORx
가T
타입인 경우 →T
타입의x
를 리턴한다.
위와 같은 방법에 추가로 어떤 인터페이스의 값이 특정 타입인지를 확인하다가 런타임 에러를 방지하기 위해서는 (panic 방지)
v, ok := n.(int)
위와 같이 특정 타입인지를 확인하기 위해 ok값을 받을 수도 있다.
assert한 타입이 맞으면 ok는 true, 아니면 false가 될 것이고, ok일때는, v에 concrete value가 assign 된다.
a tour of go의 예시를 보고 이해해보자
package main
import "fmt"
func main() {
var i interface{} = "hello"
s := i.(string)
fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
f, ok := i.(float64)
fmt.Println(f, ok)
f = i.(float64) // panic
fmt.Println(f)
}
참고자료
https://iamjjanga.tistory.com/47#recentComments
'[Golang]' 카테고리의 다른 글
[Golang gin] io.NopCloser란? (ioutil.ReadAll()로 읽은 content를 날리지 않는 법) (io.ReadCloser란) (2) | 2022.02.09 |
---|---|
[golang] Unit Test 마스터하기 (step1. 테스트 전에 미리 설정이 필요할때) (testify suite패키지) (0) | 2021.12.08 |
[golang] time.After이란? (memory leak 가능성) (0) | 2021.08.30 |
[golang] Marshal, Unmarshal 차이 (0) | 2021.08.09 |
[golang] string pointer는 언제쓸까? (0) | 2021.08.09 |