golang-type关键字

type 关键字

Type关键字在Go语言中作用很重要,他主要用来实现两个功能:

go 复制代码
【自定义类型】
自定义类型底层是一种类型,但是不会拥有底层类型的方法。
自定义类型与底层类型相比是一种新类型,二者之间需要显式类型转换。
//语法
type 自定义类型 底层类型

【类型别名】
类型别名就是为原类型取个新名字,完整拥有原类型的方法。
//语法
type 类型别名 = 原类型

自定义类型

基本语法

go 复制代码
type 自定义类型 底层类型;

声明自定义类型并赋值

声明自定义类型

在Go 语言中,基础类型有下面几种:

go 复制代码
bool byte complex64 complex128 error float32 float64
int int8 int16 int32 int64 rune string
uint uint8 uint16 uint32 uint64 uintptr

使用 type 关键字可以定义我们自己的类型,如我们可以使用type定义一个新的结构体,也可以基于一个已经存在的类型来定义新类型,然后就可以在我们的代码中使用新的类型名字,这称为自定义类型,如:

go 复制代码
type IZ int

这里IZ就是完全是一种新类型,然后我们可以使用下面的方式声明变量:

go 复制代码
var a IZ =5

这里我们可以看到 int 是变量 a 的底层类型,这也使得它们之间存在相互转换的可能。

理解

在已有的类型上映射出一个新类型,该类型可以存储与底层变量一样的值。

sh 复制代码
1.自定义类型不拥有原类型的方法,只是用来存储原类型一样的值。

好比于我们不满足golang之前对整数的处理方法,于是我们定义一种新类型来存储整数,然后重新给他加方法。

type IZ int 中,IZ 就是基于int 类型构建的新类型,这称为自定义类型。然后就可以使用 IZ 来操作 int 类型的数据。

多个自定义类型声明

如果我们有多个类型需要定义,可以使用因式分解关键字的方式,例如:

Go 复制代码
type (
   IZ int
   FZ float64
   STR string
)

显式转换

自定义类型与原类型已经分道扬镳了,虽然变量的形式长的一样,但是他们属于不同的类型,拥有着不同的方法。

就好比亚洲人,日本人和韩国人虽然都属于亚洲人,但是实际上属于不同国家,如果要调整国籍需要显式转换。

5是整数,int和我们的自定义类型IZ都是整数,但实际上是不同类型,需要也需要显式转换。

举例

go 复制代码
type IZ int
var a IZ = 5
//虽然a的值是5,也是整数,但是他已经属于IZ,
//如果我们要将他给int,就需要显式转换
b := int(a) 

官方解释

每个值在经过编译后都必须属于某个类型(编译器必须能够推断出所有值的类型),因为 Go 语言是一种静态类型语言。

在必要以及可行的情况下,一个类型的值可以被转换成另一种类型的值。

由于 Go 语言不存在隐式类型转换,因此所有的转换都必须显式说明,就像调用一个函数一样(类型在这里的作用可以看作是一种函数):

go 复制代码
//强制转换的语法
valueOfTypeB = typeB(valueOfTypeA)
//中文
类型 B 的值 = 类型 B(类型 A 的值)

方法验证

自定义类型不具备原类型的方法。

go 复制代码
package struct_knowledge

import "fmt"

//基础类型结构体
type Age struct{
	age int
} 
//自定义类型
type Myage Age

//我们给Age类型添加一个方法
func (a Age) IsAdult(){
	if(a.age>=18){
		fmt.Println("已经成年")
	}else{
		fmt.Println("未成年")
	}
}
//验证自定义类型是否有底层类型的方法
func CustomerType(){
	var age1 = Age{
		age:19,
	}

	var age2 = Myage{
		age:20,
	}

	age1.IsAdult()

	/*
		报错:
		age2.IsAdult undefined
		type Myage has no field or method IsAdult
	*/
	// age2.IsAdult()
}

通过Type 关键字在原有类型基础上构造出一个新类型,我们需要针对新类型来重新创建新方法。

自定义类型存在意义

我们不能给私有类型添加方法,例如

go 复制代码
bool byte complex64 complex128 error float32 float64
int int8 int16 int32 int64 rune string
uint uint8 uint16 uint32 uint64 uintptr

他们都是小写开头,也就是golang的本地私有类型,如果我们向给他们添加方法就会报错,例如:

golang的本地私有类型,指的是上述这些golang自带类型。我们自己定义的私有类型不算。

go 复制代码
//给golang的私有类型添加方法会报错
// cannot define new methods on non-local type int
func (a int) IsOdd()bool{
	if(a%2==0){
		fmt.Println("a是偶数")
		return false
	}else{
		fmt.Println("a是奇数")
		return true
	}
}

报错信息

go 复制代码
 cannot define new methods on non-local type int

所以我们想给原类型添加新方法只能用自定义类型来映射底层类型。

后续说到的类型别名,本质上是给底层类型重命名,所以无法解决这个问题。

类型别名

基本语法

go 复制代码
type 类型别名 = 原类型名;

别名类型和原类型,这两个类型可以视为完全一致,能交换使用。

我们把type 类型别名定义的新类型叫做别名类型。

举例

go 复制代码
package type_knowledge

import "fmt"

type Myint = int 

func GetInt(){
	var a Myint = 20
	var b int
    //不需要类型转换,因为二者本质上是同一类型
	b = a 
	fmt.Printf("b的值为%d\n",b)
}

理解

就好比于,你在中国叫张三,去了国外取了个英文名Sam,本质上还是一个人。

方法验证

别名类型本质上还是原类型,所以拥有原类型的一切方法与性质。

本地类型不允许添加方法

go 复制代码
type Myint = int
//给golang的私有类型添加方法会报错
// cannot define new methods on non-local type int
func (a Myint) IsOdd()bool{
	if(a%2==0){
		fmt.Println("a是偶数")
		return false
	}else{
		fmt.Println("a是奇数")
		return true
	}
}

从报错信息可知,golang是凭借原类型来识别别名类型的。

测试方法

go 复制代码
package type_knowledge

import "fmt"

type Book struct{
	price int
}

type MyBook = Book 

func (a Book) IsCheap() bool{
	if(a.price>=20){
		fmt.Println("The book is expensive")
		return false
	}else{
		fmt.Println("The book is cheap")
		return true
	}
}

func OtherNameType(){
	book1 := Book{
		price: 25,
	}
	book2 := MyBook{
		price: 30,
	}

	book1.IsCheap()
	book2.IsCheap()
}

别名类型拥有原类型的所有方法。

注意事项

由于别名类型本质上就是原类型,所以我们给别名类型添加方法也就是在给原类型添加方法。

别名类型存在的意义

字符在计算机中是用数字存储的,所以没有必要再创造一种新类型,所以golang存储字符的类型的底层源码为:

go 复制代码
type byte = int8
type rune = int32
相关推荐
侠客行03171 天前
Mybatis连接池实现及池化模式
java·mybatis·源码阅读
蛇皮划水怪1 天前
深入浅出LangChain4J
java·langchain·llm
灰子学技术1 天前
go response.Body.close()导致连接异常处理
开发语言·后端·golang
老毛肚1 天前
MyBatis体系结构与工作原理 上篇
java·mybatis
风流倜傥唐伯虎1 天前
Spring Boot Jar包生产级启停脚本
java·运维·spring boot
Yvonne爱编码1 天前
JAVA数据结构 DAY6-栈和队列
java·开发语言·数据结构·python
Re.不晚1 天前
JAVA进阶之路——无奖问答挑战1
java·开发语言
熬夜有啥好1 天前
数据结构——哈希表
数据结构·散列表
你这个代码我看不懂1 天前
@ConditionalOnProperty不直接使用松绑定规则
java·开发语言
fuquxiaoguang1 天前
深入浅出:使用MDC构建SpringBoot全链路请求追踪系统
java·spring boot·后端·调用链分析