Contents
1.7. 类型别名¶
1.7.1. 1.类型别名¶
类型别名是Go 1.9 版本添加的新功能,主要用于代码升级、迁移中类型的兼容性问题。
在C/C++ 语言中,代码重构升级可以使用宏快速定义新的一段代码。Go语言中没有选择加入宏, 而是将解决重构中最麻烦的类型名变更问题。
Go 1.9版本之前的内建类型定义代码是这样写的:
type byte uint8
type rune int32
而在Go 1.9版本之后变为:
type byte = uint8
type rune = int32
1.7.2. 2.区分类型别名与类型定义¶
类型别名的写法为:
type TypeAlias = Type
package main
import "fmt"
// 将NewInt定义为int类型
type NewInt int
// 给int取一个IntAlias的别名
type IntAlias = int
func main() {
var a NewInt
var a2 IntAlias
fmt.Printf("a type : %T\n", a)
fmt.Printf("a2 type : %T\n", a2)
}
//a type : main.NewInt
//a2 type : int
1.7.3. 3.非本地类型不能定义方法¶
能够随意地为各种类型起名字,是否意味着可以在自己包里为这些类型任意添加方法?
package main
import "time"
// 定义time.Duration的别名为MyDuration
type MyDuration = time.Duration
// 为MyDuration添加一个函数
func (m MyDuration) EasySet(a string) {}
func main() {
}
编译上面代码报错,信息如下:
cannot define new methods on non-local type time.Duration
编译器提示:不能在一个非本地的类型time.Duration上定义新方法。非本地方法指的就是使用time.Duration的代码所在的包,也就是main包。 因为time.Duration是在time包中定义的,在main包中使用。time.Duration包与main包不在同一个包中,因此不能为不在一个包中的类型定义方法。
解决这个问题有下面两种方法:
将第8行修改为type MyDuration time.Duration,也就是将MyDuration从别名改为类型。
将MyDuration的别名定义放在time包中。
package main
import "time"
// 定义time.Duration的别名为MyDuration
type MyDuration time.Duration
// 为MyDuration添加一个函数
func (m MyDuration) EasySet(a string) {}
func main() {
}
1.7.4. 4.在结构体成员嵌入时使用别名¶
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
这个例子中,FakeBrand是Brand的一个别名。在Vehicle中嵌入FakeBrand和Brand并不意味着嵌入两个Brand。FakeBrand的类型会以名字的方式保留在Vehicle的成员中。 在调用Show()方法时,因为两个类型都有Show()方法,会发生歧义,证明FakeBrand的本质确实是Brand类型。