自定义类型

在 Go 语言中,自定义类型指的是使用 type 关键字定义的新类型,它可以是基本类型的别名,也可以是结构体、函数等组合而成的新类型。自定义类型可以帮助我们更好地抽象和封装数据,让代码更加易读、易懂、易维护

结构体就是自定义类型中的一种

举例

后端给前端返回特定的状态码,为了把状态码和其他的数字区分开来

以下是一个假设的逻辑

go
func webSever(name string) int {
if name == "1" {
return 1001
}
if name == "2" {
return 1002
}
return 0
}

如果后期状态码变了,并不好维护,可以存一个映射关系

以下是改进

go
const (
SuccessCode = 0 // 成功
ServiceErrorCode = 1001 // 服务错误
NetworkErrorCode = 1002 // 网络错误
)
// 根据code返回msg信息
func getMsg(code int) (msg string) {
switch code {
case SuccessCode:
msg = "成功"
case ServiceErrorCode:
msg = "服务错误"
case NetworkErrorCode:
msg = "网络错误"
default:
msg = "未知错误"
}
return
}
func webSever(name string) (code int, msg string) {
if name == "1" {
return ServiceErrorCode, getMsg(ServiceErrorCode)
}
if name == "2" {
return NetworkErrorCode, getMsg(NetworkErrorCode)
}
return SuccessCode, getMsg(SuccessCode)
}

如果这时候getMsg传入一个 code 以外的值,并不会报错

新的改进,自己自定义一个 Code 类型

go
type Code int

声明变量的时候同步声明类型

go
const (
SuccessCode Code = 0 // 成功
ServiceErrorCode Code = 1001 // 服务错误
NetworkErrorCode Code = 1002 // 网络错误
)

定义函数的时候形参也要同步修改

go
func getMsg(code Code) (msg string) {
}
func webSever(name string) (code Code, msg string) {
}

此时可以发现,getMsg是一个冗余的方法,可以直接绑定到自定义类型Code,定义完成之后就可以直接使用.语法调用

go
func (c Code) GetMsg() string {
switch c {
case SuccessCode:
return "成功"
case ServiceErrorCode:
return "服务错误"
case NetworkErrorCode:
return "网络错误"
default:
return "未知错误"
}
return ""
}
go
func webSever(name string) (code Code, msg string) {
if name == "1" {
return ServiceErrorCode, ServiceErrorCode.GetMsg()
}
if name == "2" {
return NetworkErrorCode, NetworkErrorCode.GetMsg()
}
return SuccessCode, SuccessCode.GetMsg()
}

此时还可以继续修改getMsg方法返回两个值

go
func (c Code) Ok() (code Code, msg string) {
return c, c.GetMsg()
}
go
func webSever(name string) (code Code, msg string) {
if name == "1" {
return ServiceErrorCode.Ok()
}
if name == "2" {
return NetworkErrorCode.Ok()
}
return SuccessCode.Ok()
}

完整代码

go
type Code int
// 给自定义方法绑定方法
func (c Code) GetMsg() string {
switch c {
case SuccessCode:
return "成功"
case ServiceErrorCode:
return "服务错误"
case NetworkErrorCode:
return "网络错误"
default:
return "未知错误"
}
return ""
}
func (c Code) Ok() (code Code, msg string) {
return c, c.GetMsg()
}
const (
SuccessCode Code = 0 // 成功
ServiceErrorCode Code = 1001 // 服务错误
NetworkErrorCode Code = 1002 // 网络错误
)
func webSever(name string) (code Code, msg string) {
if name == "1" {
return ServiceErrorCode.Ok()
}
if name == "2" {
return NetworkErrorCode.Ok()
}
return SuccessCode.Ok()
}

类型别名

和自定义类型很像,但是有一些地方和自定义类型有很大差异

  • 不能绑定方法

    go
    type MyCode int //自定义类型
    type MyAlias = int //类型别名
  • 打印类型还是原始类型

    go
    const myCode MyCode = 1
    const myAlias MyAlias = 1
    func main() {
    fmt.Printf("%v %T\n", myCode, myCode)
    fmt.Printf("%v %T\n", myAlias, myAlias)
    }
    1 main.MyCode
    1 int
  • 和原始类型比较,类型别名不用转换

    自定义类型直接和其他的变量比较会报错

需要进行转换到同一个类型

go
if int(myCode) == age {
}
go
if myCode == MyCode(age) {
}
go
if myAlias == age {
}