32、Go 结构体 - type 类型别名和用户自定义类型
hi,我是温新
在 Go 语言中,自定义类型指的是使用 type 关键字定义的新类型,它可以是基本类型的别名,也可以是结构体、函数等组合而成的新类型。自定义类型可以帮助我们更好地抽象和封装数据,让代码更加易读、易懂、易维护。
当基本的数据类型(string、int、float、bool等)不够用时,用户可以使用 type
关键字进行自定义类型。type 只有两种使用方式,一种类型别名
,另一种是自定义类型
。
本篇文章将学习这两种方式。
类型别名与类型定义
类型别名
语法如下:
type TypeAlias = Type
// type 类型别名 = 类型
类型别名规定:TypeAlias
只是 Type
的别名,本质上 TypeAlias
与 Type
是同一个类型。如同李四的别名是二狗子,不不管你叫二狗子还是李四,都是他。
类型定义
语法如下:
type newType = Type
// type 新类型 = 类型
案例:
package main
import "fmt"
// 类型定义
type newInt int
// 类型别名
type newString = string
func main() {
// 将 newStr 类型声明为 newString
var newStr newString = "王美丽"
// 将 num 声明为 newInt 类型
var num newInt = 19
fmt.Printf("newStr 的数据类型 %T,内容是 %s\n", newStr, newStr)
fmt.Printf("num 的数据类型 %T,内容是 %d\n", num, num)
}
输出结果
newStr 的数据类型 string,内容是 王美丽
num 的数据类型 main.newInt,内容是 19
类型声明与类型定义有什么区别?
两者之间的区别在于,类型别名只是给现有类型取了一个别名;而类型定义则是完全定义了一种新的类型。
非本地类型不能定义方法
package main
import "time"
// 定义一个方法别名
type myTime = time.Time
func main() {
}
// 为 myTime 添加一个函数
func (m myTime) getMyTime() {
}
(m myTime)
这里会报错:Cannot define new methods on the non-local type 'time.Time'
。不能在一个非本地的类型 time.Duration
上定义新的方法。非本地类型指的就是 time.Duration 不是在 main 包中定义的,而是在 time 包中定义的,与 main 包不在同一个包中,因此不能为不在一个包中的类型定义方法。
解决这个问题有两种方法,如下:
1、type myTime =time.Time
修改为type myTime time.Duration
,也就是把 myTime
从别名改为类型;
2、把 myTime
的别名定义放在 time
包中。
用户自定义类型
在 Go 语言中,type 是一个非常重要的关键字,它的常用用法有这几种:类型别名、类型定义、定义结构体、定义接口、类型查询、定义函数。
定义结构体
在之前的文章已经学习过结构体,这里作一个简单的回顾吧。
package main
import "fmt"
func main() {
p1 := MyPerson{
name: "王美丽",
gender: "女",
}
fmt.Println(p1)
}
// 定义结构体
type MyPerson struct {
name, gender string
}
定义接口
关于接口,这里只作一个简单的案例进行演示。关于接口的知识将在后续文章中学习。
package main
import "fmt"
func main() {
xiaomi := new(Xiaomi)
xiaomi.name = "小米13"
xiaomi.Call() // 小米13:可以打电话
}
// 定义一个电话接口
type Phone interface {
Call()
}
// 定义结构体
type Xiaomi struct {
name string
}
// 定义一个方法
func (xiaomi *Xiaomi) Call() {
fmt.Printf("%s:可以打电话", xiaomi.name)
}
定义函数
package main
import (
"fmt"
"strconv"
)
func main() {
result := getMyFun()
fmt.Println(result(10, 10))
}
// 定义一个函数
type MyFun func(int, int) string
// 该函数返回值是 MyFun 类型
func getMyFun() MyFun {
fun := func(m, n int) string {
str := strconv.Itoa(m) + strconv.Itoa(n)
return str
}
return fun
}
类型查询
类型查询,就是根据变量来查询它的类型。Golang 中有一个特殊的类型interface{}
,这个类型可以被赋予任何类型的变量的值,如果想要知道哪个类型的赋值给了interface{}
类型变量,就需要使用类型查询,案例如下:
package main
import "fmt"
func main() {
var variableName interface{} = "abc"
switch v := variableName.(type) {
case string:
fmt.Println("字符串")
case int:
fmt.Println("整型")
default:
fmt.Println("其他类型", v)
}
}
如果使用.(type)
查询类型的变量不是 interface{}
类型,则在编译时报错:cannot type switch on non-interface value a (type string)
。
若在 switch
以外的地方使用.(type)
,则在编译时报错:use of .(type) outside type switch
。
由此可知,使用type
进行类型查询时,只能在switch
中使用,且使用类型查询必须是interface{}
。
后面要停更 2 个星期了,今天把库存都发了出来。我们 9 月中旬再见。