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
相关推荐
CS创新实验室26 分钟前
数据结构:栈的应用举例——进制转换
数据结构·计算机考研·408考研
百香果果ccc1 小时前
Maven的继承和聚合
java·hive·maven
极客先躯1 小时前
高级java每日一道面试题-2025年3月04日-微服务篇[Eureka篇]-Eureka是什么?
java·微服务·eureka·集群部署·健康检查·组件和架构·自我保护机制
幸好我会魔法1 小时前
RabbitMQ实现定时/延迟任务
java·rabbitmq·java-rabbitmq
奋进的小暄1 小时前
贪心算法(7)(java) 分发饼干
数据结构·算法·贪心算法
Cloud_.1 小时前
Spring Boot 集成高德地图电子围栏
java·spring boot·后端
搞不懂语言的程序员1 小时前
单例模式详解(java)
java·开发语言·单例模式
Python破壁人手记2 小时前
《我的Python觉醒之路》之转型Python(十五)——控制流
java·服务器·开发语言·网络·python
Michaelwubo2 小时前
jenkins 配置邮件问题整理
java·运维·jenkins
siy23332 小时前
[c语言日寄]浮点数的排序
c语言·开发语言·数据结构·笔记·学习