自定义类型和类型别名
2026年9月6日
type 可以干两件事:做出一种新类型,或给已有类型起别名。结构体是自定义类型的一种;给状态码、ID 这类值单独起类型,调用处就不容易传错。
自定义类型
type Code int
const (
CodeOK Code = 0
CodeFail Code = 1
)
func write(c Code) {
fmt.Println(c)
}
write(CodeOK)
// write(0) // 编译错误:int 不是 Code
go
Code 和 int 底层一样,但在类型系统里是两种类型,互相要用必须显式转换:Code(0)、int(c)。
可以给它绑方法:
func (c Code) Text() string {
if c == CodeOK {
return "ok"
}
return "fail"
}
go
结构体、函数类型、切片都可以这样定义。响应码、用户 ID、带单位的数字,用自定义类型比满地 int 清楚。
类型别名
等号是别名,不是新类型:
type Code = int
go
和自定义类型差在三点:
- 不能单独绑方法(方法算在原来的
int上,你再绑会冲突或根本加不到「新类型」上) %T打出来还是原来的类型,比如int- 和原类型比较、赋值不用转换
type Code = int
var c Code = 1
var n int = c // 可以直接赋
fmt.Printf("%T\n", c) // int
go
标准库里的例子:byte 是 uint8 的别名,rune 是 int32 的别名。type byte = uint8。
需要「换个名字、还当原来那个用」时用别名;需要「看起来像 int、但不能随便拿 int 冒充」时用自定义类型。