Golang 学习笔记06-自定义类型和类型别名

自定义类型

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

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

举例

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

以下是一个假设的逻辑

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

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

以下是改进

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 类型

type Code int

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

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

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

func getMsg(code Code) (msg string) {

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

}

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

func (c Code) GetMsg() string {
	switch c {
	case SuccessCode:
		return "成功"
	case ServiceErrorCode:
		return "服务错误"
	case NetworkErrorCode:
		return "网络错误"
	default:
		return "未知错误"
	}
	return ""
}

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方法返回两个值

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

完整代码

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()
}

类型别名

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

  • 不能绑定方法

    type MyCode int    //自定义类型
    type MyAlias = int //类型别名

  • 打印类型还是原始类型

    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
  • 和原始类型比较,类型别名不用转换

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

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

if int(myCode)	 == age {

}
if myCode == MyCode(age) {

}
if myAlias == age {

}