首页 后端开发 Golang Go语言类型别名是什么

Go语言类型别名是什么

Jan 10, 2023 pm 05:58 PM
golang go语言 类型别名

在Go语言中,类型别名就是为已存在的“类型”定义一个别名,可以使用type关键字来定义,语法“type TypeAlias = Type”。类型别名是Go 1.9版本添加的新功能,主要用于解决代码升级、迁移中存在的类型兼容性问题;在 C/C++ 语言中,代码重构升级可以使用宏快速定义一段新的代码,Go语言中没有选择加入宏,而是解决了重构中最麻烦的类型名变更问题。

Go语言类型别名是什么

本教程操作环境:windows7系统、GO 1.18版本、Dell G3电脑。

Go语言 类型别名是什么

Golang 中类型别名就是为已存在的 类型 定义一个别名。Golang 中类型别名使用 type 关键字来定义。

语法

type TypeAlias = Type
登录后复制
登录后复制

参数

参数描述
type定义类型别名使用的关键字。
TypeAliasType 的别名。
Type需要起别名的类型。

类型别名是 Go 1.9 版本添加的新功能,主要用于解决代码升级、迁移中存在的类型兼容性问题。在 C/C++ 语言中,代码重构升级可以使用宏快速定义一段新的代码,Go语言中没有选择加入宏,而是解决了重构中最麻烦的类型名变更问题。

在 Go 1.9 版本之前定义内建类型的代码是这样写的:

type byte uint8
type rune int32
登录后复制

而在 Go 1.9 版本之后变为:

type byte = uint8
type rune = int32
登录后复制

这个修改就是配合类型别名而进行的修改。

区分类型别名与类型定义

定义类型别名的写法为:

type TypeAlias = Type
登录后复制
登录后复制

类型别名规定:TypeAlias 只是 Type 的别名,本质上 TypeAlias 与 Type 是同一个类型,就像一个孩子小时候有小名、乳名,上学后用学名,英语老师又会给他起英文名,但这些名字都指的是他本人。

类型别名与类型定义表面上看只有一个等号的差异,那么它们之间实际的区别有哪些呢?下面通过一段代码来理解。

package main
import (
    "fmt"
)
// 将NewInt定义为int类型
type NewInt int
// 将int取一个别名叫IntAlias
type IntAlias = int
func main() {
    // 将a声明为NewInt类型
    var a NewInt
    // 查看a的类型名
    fmt.Printf("a type: %T\n", a)
    // 将a2声明为IntAlias类型
    var a2 IntAlias
    // 查看a2的类型名
    fmt.Printf("a2 type: %T\n", a2)
}
登录后复制

代码运行结果:

a type: main.NewInt
a2 type: int
登录后复制

代码说明如下:

  • 第 8 行,将 NewInt 定义为 int 类型,这是常见的定义类型的方法,通过 type 关键字的定义,NewInt 会形成一种新的类型,NewInt 本身依然具备 int 类型的特性。

  • 第 11 行,将 IntAlias 设置为 int 的一个别名,使用 IntAlias 与 int 等效。

  • 第 16 行,将 a 声明为 NewInt 类型,此时若打印,则 a 的值为 0。

  • 第 18 行,使用%T格式化参数,打印变量 a 本身的类型。

  • 第 21 行,将 a2 声明为 IntAlias 类型,此时打印 a2 的值为 0。

  • 第 23 行,打印 a2 变量的类型。

结果显示 a 的类型是 main.NewInt,表示 main 包下定义的 NewInt 类型,a2 类型是 int,IntAlias 类型只会在代码中存在,编译完成时,不会有 IntAlias 类型。

非本地类型不能定义方法

能够随意地为各种类型起名字,是否意味着可以在自己包里为这些类型任意添加方法呢?参见下面的代码演示:

package main
import (
    "time"
)
// 定义time.Duration的别名为MyDuration
type MyDuration = time.Duration
// 为MyDuration添加一个函数
func (m MyDuration) EasySet(a string) {
}
func main() {
}
登录后复制

代码说明如下:

  • 第 8 行,为 time.Duration 设定一个类型别名叫 MyDuration。

  • 第 11 行,为这个别名添加一个方法。

编译上面代码报错,信息如下:

cannot define new methods on non-local type time.Duration
登录后复制

编译器提示:不能在一个非本地的类型 time.Duration 上定义新方法,非本地类型指的就是 time.Duration 不是在 main 包中定义的,而是在 time 包中定义的,与 main 包不在同一个包中,因此不能为不在一个包中的类型定义方法。

解决这个问题有下面两种方法:

  • 将第 8 行修改为 type MyDuration time.Duration,也就是将 MyDuration 从别名改为类型;

  • 将 MyDuration 的别名定义放在 time 包中。

在结构体成员嵌入时使用别名

当类型别名作为结构体嵌入的成员时会发生什么情况呢?请参考下面的代码。

package main
import (
    "fmt"
    "reflect"
)
// 定义商标结构
type Brand struct {
}
// 为商标结构添加Show()方法
func (t Brand) Show() {
}
// 为Brand定义一个别名FakeBrand
type FakeBrand = Brand
// 定义车辆结构
type Vehicle struct {
    // 嵌入两个结构
    FakeBrand
    Brand
}
func main() {
    // 声明变量a为车辆类型
    var a Vehicle
   
    // 指定调用FakeBrand的Show
    a.FakeBrand.Show()
    // 取a的类型反射对象
    ta := reflect.TypeOf(a)
    // 遍历a的所有成员
    for i := 0; i < ta.NumField(); i++ {
        // a的成员信息
        f := ta.Field(i)
        // 打印成员的字段名和类型
        fmt.Printf("FieldName: %v, FieldType: %v\n", f.Name, f.Type.
            Name())
    }
}
登录后复制

代码输出如下:

FieldName: FakeBrand, FieldType: Brand
FieldName: Brand, FieldType: Brand
登录后复制

代码说明如下:

  • 第 9 行,定义商标结构。

  • 第 13 行,为商标结构添加 Show() 方法。

  • 第 17 行,为 Brand 定义一个别名 FakeBrand。

  • 第 20~25 行,定义车辆结构 Vehicle,嵌入 FakeBrand 和 Brand 结构。

  • 第 30 行,将 Vechicle 实例化为 a。

  • 第 33 行,显式调用 Vehicle 中 FakeBrand 的 Show() 方法。

  • 第 36 行,使用反射取变量 a 的反射类型对象,以查看其成员类型。

  • 第 39~42 行,遍历 a 的结构体成员。

  • 第 45 行,打印 Vehicle 类型所有成员的信息。

这个例子中,FakeBrand 是 Brand 的一个别名,在 Vehicle 中嵌入 FakeBrand 和 Brand 并不意味着嵌入两个 Brand,FakeBrand 的类型会以名字的方式保留在 Vehicle 的成员中。

如果尝试将第 33 行改为:

a.Show()
登录后复制

编译器将发生报错:

ambiguous selector a.Show
登录后复制

在调用 Show() 方法时,因为两个类型都有 Show() 方法,会发生歧义,证明 FakeBrand 的本质确实是 Brand 类型。

【相关推荐:Go视频教程编程教学

以上是Go语言类型别名是什么的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前 By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解锁Myrise中的所有内容
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Go语言中用于浮点数运算的库有哪些? Go语言中用于浮点数运算的库有哪些? Apr 02, 2025 pm 02:06 PM

Go语言中用于浮点数运算的库介绍在Go语言(也称为Golang)中,进行浮点数的加减乘除运算时,如何确保精度是�...

Go的爬虫Colly中Queue线程的问题是什么? Go的爬虫Colly中Queue线程的问题是什么? Apr 02, 2025 pm 02:09 PM

Go爬虫Colly中的Queue线程问题探讨在使用Go语言的Colly爬虫库时,开发者常常会遇到关于线程和请求队列的问题。�...

Go语言中`var`和`type`关键字定义结构体的区别是什么? Go语言中`var`和`type`关键字定义结构体的区别是什么? Apr 02, 2025 pm 12:57 PM

Go语言中结构体定义的两种方式:var与type关键字的差异Go语言在定义结构体时,经常会看到两种不同的写法:一�...

Go语言中哪些库是由大公司开发或知名的开源项目提供的? Go语言中哪些库是由大公司开发或知名的开源项目提供的? Apr 02, 2025 pm 04:12 PM

Go语言中哪些库是大公司开发或知名开源项目?在使用Go语言进行编程时,开发者常常会遇到一些常见的需求,�...

在Go语言中使用Redis Stream实现消息队列时,如何解决user_id类型转换问题? 在Go语言中使用Redis Stream实现消息队列时,如何解决user_id类型转换问题? Apr 02, 2025 pm 04:54 PM

Go语言中使用RedisStream实现消息队列时类型转换问题在使用Go语言与Redis...

在 Go 语言中,为什么使用 Println 和 string() 函数打印字符串会出现不同的效果? 在 Go 语言中,为什么使用 Println 和 string() 函数打印字符串会出现不同的效果? Apr 02, 2025 pm 02:03 PM

Go语言中字符串打印的区别:使用Println与string()函数的效果差异在Go...

GoLand中自定义结构体标签不显示怎么办? GoLand中自定义结构体标签不显示怎么办? Apr 02, 2025 pm 05:09 PM

GoLand中自定义结构体标签不显示怎么办?在使用GoLand进行Go语言开发时,很多开发者会遇到自定义结构体标签在�...

VSCode中如何解决Golang泛型函数类型约束被自动删除的问题? VSCode中如何解决Golang泛型函数类型约束被自动删除的问题? Apr 02, 2025 pm 02:15 PM

VSCode中Golang泛型函数类型约束的自动删除问题在使用VSCode编写Golang代码时,用户可能会遇到一个奇怪的问题。当...

See all articles