Go 언어는 정적 강타입 시스템을 구현하고 있습니다. 이는 각각의 변수의 타입이 컴파일 시간에 알려져 있으며, 컴파일러가 호환되지 않는 타입 간의 연산을 허용하지 않는다는 의미입니다.
두 가지 타입 변환 방식이 있습니다:
명시적 타입 변환 예시:
var i int = 42 var f float64 = float64(i)
type assertion 예시:
var i interface{} = "hello" s, ok := i.(string) if ok { fmt.Println("문자열 값:", s) } else { fmt.Println("i는 문자열이 아님") }
타입 변환은 오직 호환 가능한 기본 타입 간에만 가능합니다 (int → float64, rune → int32, 그러나 string → int 는 불가능합니다).
interface{}는 nil 값을 저장할 수 있습니까? 그리고 인터페이스 타입의 변수에 실제로 nil인지 확인하는 올바른 방법은 무엇입니까?
일반적인 함정은 nil 값을 포함하는 인터페이스를 nil과 직접 비교하는 것입니다:
var err error = nil var i interface{} = err fmt.Println(i == nil) // true가 예상되지만 false가 나옵니다!
올바른 방법:
인터페이스 자체가 nil이고 내부 값이 nil인지 확인해야 합니다:
if i == nil || reflect.ValueOf(i).IsNil() { fmt.Println("i는 실제로 nil입니다") }
이야기
백엔드 프로젝트에서 개발자는 다양한 오류를 interface{}를 통해 처리하려고 했고, 그들을 nil과 비교했습니다. 결과적으로, 오류를 올바르게 감지할 수 없었고, 숨겨진 버그와 클라이언트에게 오류를 반환하는 잘못된 논리가 발생했습니다.
이야기
float64와 int 간의 명시적 변환 없이의 이주 과정에서 데이터 손실이 발생했습니다: 값이 잘못 반올림되거나 잘못 전달되었습니다. Go 컴파일러는 이러한 작업에 대해 명시적 변환을 요구합니다.
이야기
map[string]interface{}에서 인터페이스 값을 역직렬화할 때 (예: JSON으로부터) 예상치 못한 number 타입 (float64)이 type assertion을 추가 검증 없이 사용했을 때 패닉을 일으켜 서비스가 런타임 오류로 중단되었습니다.