golang快速入门:类型系统

自定义数据类型

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

在 Go 语言中,使用 type 关键字可以定义一个新的类型,语法如下:

bash 复制代码
type newType oldType

其中,NewType 是新类型的名称,OldType 可以是任何基本类型或现有类型的别名,通过这种方式可以创建一个新类型,使得这个新类型具有与原有类型不同的特性。

自定义数据类型是一种新的数据类型,与其基于的Go内置数据类型 是两种数据类型,无法用来进行 运算符计算 (算数运算符、逻辑运算符、关系运算符、位运算符等)。

less 复制代码
type MyInt int
 
var a MyInt = 10
var b int = 10
 
if a==b {
    fmt.Println("hello world")
}

程序报错

ini 复制代码
invalid opeartion: a == b (mismatched types Myint and int)

如果想要参与运算,必须进行转换。

scss 复制代码
if a==MyInt(b) {
    fmt.Println("hello world")
}

不仅可以定义基本数据类型,也可以定义函数类型

go 复制代码
type myFunc func(int) int

func sum10(num int) int {
    fmt.Println(num*10)
}
 
 
func main() {
    newFunc := myFunc(sum10)
}

定义成员方法

可以为自定义类型定义成员方法,下面基于 ​​​int​​​​ 设置了 ​​​​Code​​​ 类型(这是一个新类型,不是类型别名),在使用的时候也要通过 ​​​​Code​​​ 类型进行声明,不过本质上它仍然是一个整型数字,你可以把具体的数值看做是 ​​​​Code​​​ 类型的实例。

go 复制代码
package main

import "fmt"

type Code int

const (
  SuccessCode    Code = 0
  ValidCode      Code = 7 // 校验失败的错误
  ServiceErrCode Code = 8 // 服务错误
)

func (c Code) GetMsg() string {

  return "成功"
}

func main() {
  fmt.Println(SuccessCode.GetMsg())
}

同理,自定义函数类型也可以定义成员方法

go 复制代码
type myFunc func(int) int
 
func (mf myfunc) sum(a,b int) int {
    c := a + b
    return mf(c)
}

自定义函数类型结合接口、结构体使用,完成一些复杂的逻辑

go 复制代码
type sumable interface {
    sum(int, int) int
}
 
// myFunc继承sumable接口
type myFunc func(int) int
 
func (f myFunc) sum (a, b int) int {
    res := a + b
    return f(res)
}
 
func sum10(num int) int {
    return num * 10
}
 
func sum100(num int) int {
    return num * 100
}
 
// icansum结构体继承sumable接口
type icansum struct {
    name string
    res int
}
 
func (ics *icansum) sum(a, b int) int {
    ics.res = a + b
    return ics.res
}
 
// handler只要是继承了sumable接口的任何变量都行,我只需要你提供sum函数就好
func handlerSum(handler sumable, a, b int) int {
    res := handler.sum(a, b)
    fmt.Println(res)
    return res
}
 
func main() {
    newFunc1 := myFunc(sum10)
    newFunc2 := myFunc(sum100)
 
    handlerSum(newFunc1, 1, 1)    // 20
    handlerSum(newFunc2, 1, 1)    // 200
 
    ics := &icansum{"I can sum", 0}
    handlerSum(ics, 1, 1)         // 2
}

上面可以看出sum10 和 sum10(1) 之间的区别,前者是类型为 func(int) int 的变量,后者是函数调用。其次,newFunc1 := myFunc(sum10) 的意思是将 sum10 这个变量的类型转换成 myFunc 类型并赋值给 newFunc1,newFunc1 其实就是套了一个类型叫 myFunc 的马甲的 sum10 变量。那么对于第43行 handlerSum(newFunc1, 1, 1),接受了一个 newFunc1 这个函数变量传递进来,并调用了其 sum 函数即 newFunc1.sum(1, 1),该 sum 函数的定义是先进行 res:=a+b 的加法操作,然后调用 f(res) 即 newFunc1(res) 来返回。最终,newFunc1是什么?不就是被转换成了 myFunc 类型的 sum10 嘛,本质上就是一个函数变量,那么执行 newFunc1() 其实等同于执行 sum10()。所以运算过程是先进行了 a + b 的加法,然后针对这个加法的结果进行不同的干预,你可以自定义任何一个函数(比如本例中的 sum10、sum100),只要能套上 myFunc 这个马甲(可将该变量类型转换成 myFunc ),就能对 a + b 的结果进行自定义的干预。

类型别名

等于是给基础类型换一个别名。

go 复制代码
type intAlias = int

类型别名和自定义类型的区别

go 复制代码
type AliasInt = int
type MyInt int
  1. 不能绑定方法
scss 复制代码
//自定义类型可以定义成员方法
func (m MyInt) MyIntMethod() {

}

// AliasIntMethod 类型别名 不可以绑定方法
func (m AliasInt) AliasIntMethod() {

}
//别名绑定方法会报错 cannot define new methods on non-local type
  1. 打印类型还是原始类型
java 复制代码
var MyIntNum MyInt = 0
var AliasIntNum AliasInt = 0

//自定义类型不是原类型
fmt.Printf("%v, %T \n", MyIntNum, MyIntNum) //0 ,main.MyInt

//别名打印出来是原类型
fmt.Printf("%v %T \n", AliasIntNum, AliasIntNum)//0 ,int 
  1. 和原始类型比较,类型别名不用转换
csharp 复制代码
 var age int = 0
 //别名比较不用转换类型
fmt.Println(AliasIntNum == age)


//必须转换之后才能和原始类型比较
//invalid operation: MyIntNum == age (mismatched types MyInt and int)
fmt.Println(int(MyIntNum) == age) 

总结

  • 自定义数据类型是一种新的数据类型,与其基于的Go内置数据类型 是两种数据类型,无法用来进行 运算符计算 (算数运算符、逻辑运算符、关系运算符、位运算符等)
  • 类型别名 是其基于的Go内置数据类型的一种别名,二者是同一种数据类型,可以用来进行运算符计算
相关推荐
孤雪心殇3 小时前
简单易懂,解析Go语言中的Map
开发语言·数据结构·后端·golang·go
小突突突5 小时前
模拟实现Java中的计时器
java·开发语言·后端·java-ee
web137656076435 小时前
Scala的宝藏库:探索常用的第三方库及其应用
开发语言·后端·scala
闲猫5 小时前
go 反射 interface{} 判断类型 获取值 设置值 指针才可以设置值
开发语言·后端·golang·反射
LUCIAZZZ6 小时前
EasyExcel快速入门
java·数据库·后端·mysql·spring·spring cloud·easyexcel
Asthenia04126 小时前
依托IOC容器提供的Bean生命周期,我们能在Bean中做些什么?又能测些什么?
后端
Ase5gqe6 小时前
Spring中的IOC详解
java·后端·spring
小万编程7 小时前
基于SpringBoot+Vue奖学金评比系统(高质量源码,可定制,提供文档,免费部署到本地)
java·spring boot·后端·毕业设计·计算机毕业设计·项目源码
南雨北斗7 小时前
ThinkPHP6控制器方法返回的 Content-Type类型
后端
zhuyasen7 小时前
告别低效!Go 开发框架 Sponge 与 AI 助手深度联动,打造极速开发新体验
低代码·go·deepseek