type A B 와 같은 형식으로 커스텀 타입(완전히 새로운 타입)을 만들 때 사용
완전히 새로운 타입 생성: 기존 타입(B)의 형태를 빌려오지만, 컴파일러는 이를 완전히 다른 새로운 타입(A)으로 취급.
형변환(Casting) 필수: 근본이 같은 타입이더라도, 다른 타입으로 간주되므로 섞어 쓰려면 명시적으로 형변환을 해야함.
고유한 메서드 정의 가능: 새로운 타입이므로, 해당 타입만을 위한 전용 메서드를 만들어 붙일 수 있음.
package main
import "fmt"
// int를 기반으로 새로운 커스텀 타입 'MyInt' 정의
type MyInt int
func main() {
var a int = 10
var b MyInt = 20
// a = b // ❌ 에러 발생: int와 MyInt는 다른 타입!
a = int(b) // ✅ 명시적 형변환을 해야만 대입 가능
fmt.Println(a)
}
type A = B 와 같은 형식으로 타입에 별칭을 붙일 때 사용
단순한 별명 부여: 새로운 타입을 만드는 것이 아니라, 기존 타입(B)에 새로운 이름(A)표를 하나 더 붙여준 것임.
형변환 불필요: 완전히 동일한 타입이므로, 명시적인 형변환 없이 자유롭게 섞어 쓸 수 있음.
새로운 메서드 정의 불가: 별칭을 통해 새로운 메서드를 추가할 수는 없음. (단, 원본 타입의 메서드는 그대로 사용 가능)
주요 사용처: 대규모 리팩토링 시 패키지 이동에 따른 호환성 유지, 또는 길고 복잡한 타입명(interface{})을 짧게(any) 줄여 쓸 때 사용.
package main
import "fmt"
// int와 완전히 동일한 'MyAlias'라는 별명 생성
type MyAlias = int
func main() {
var a int = 10
var b MyAlias = 20
a = b // ✅ 에러 없음! 둘은 완전히 똑같은 타입이기 때문
fmt.Println(a)
}
golang에서 any라는 타입은 go 내장 패키지(builtin.go)에서 type any = interface{}로 선언되어 있음.
이때 빈 인터페이스interface{}는 어떠한 메서드도 요구되지 않음. 즉, 조건이 아예 없기 때문에 모든 타입들(int, string, bool 등등)이 들어갈 수 있음.
package main
import "fmt"
// Go 내부에 실제로 선언되어 있는 타입 별칭 예시
// type any = interface{}
// 1. 기존 방식: interface{}를 인자로 받는 함수
func printWithInterface(val interface{}) {
fmt.Printf("[interface{}] 값: %v\n", val)
}
// 2. 새로운 방식: any를 인자로 받는 함수
func printWithAny(val any) {
fmt.Printf("[any] 값: %v\n", val)
}
func main() {
var a interface{} = "Hello"
var b any = 123
// ✅ 호환성 1: interface{} 변수를 any를 받는 함수에 전달
// (둘은 완벽히 같은 타입이므로 형변환 없이 작동)
printWithAny(a)
// ✅ 호환성 2: any 변수를 interface{}를 받는 함수에 전달
printWithInterface(b)
// ✅ 호환성 3: 별다른 형변환 없이 서로 대입도 가능
a = b
fmt.Printf("대입 후 값: %v\n", a)
}