《Go语言四十二章经》第十七章 type关键字
type关键字在Go语言中作用很重要,比如定义结构体,接口,还可以自定义类型,定义类型别名等。自定义类型由一组值以及作用于这些值的方法组成,类型一般有类型名称,往往从现有类型组合通过type关键字构造出一个新的类型。
17.1 type 自定义类型
在Go 语言中,基础类型有下面几种:
bool byte complex64 complex128 error float32 float64
int int8 int16 int32 int64 rune string
uint uint8 uint16 uint32 uint64 uintptr
使用 type 关键字可以定义我们自己的类型,如我们可以使用type定义一个新的结构体,但也可以把一个已经存在的类型作为基础类型而定义新类型,然后就可以在我们的代码中使用新的类型名字,这称为自定义类型,如:
type IZ int
这里IZ就是完全是一种新类型,然后我们可以使用下面的方式声明变量:
var a IZ = 5
这里我们可以看到 int 是变量 a 的底层类型,这也使得它们之间存在相互转换的可能。
如果我们有多个类型需要定义,可以使用因式分解关键字的方式,例如:
type (
IZ int
FZ float64
STR string
)
在 type IZ int 中,IZ 就是在 int 类型基础构建的新名称,这称为自定义类型。然后就可以使用 IZ 来操作 int 类型的数据。使用这种方法定义之后的类型可以拥有更多的特性,但是在类型转换时必须显式转换。
每个值都必须在经过编译后属于某个类型(编译器必须能够推断出所有值的类型),因为 Go 语言是一种静态类型语言。在必要以及可行的情况下,一个类型的值可以被转换成另一种类型的值。由于 Go 语言不存在隐式类型转换,因此所有的转换都必须显式说明,就像调用一个函数一样(类型在这里的作用可以看作是一种函数):
valueOfTypeB = typeB(valueOfTypeA)
类型 B 的值 = 类型 B(类型 A 的值)
type TZ int 中,新类型不会拥有原基础类型所附带的方法,如下面代码所示:
package main
import (
"fmt"
)
type A struct {
Face int
}
type Aa A // 自定义新类型Aa,没有基础类型A的方法
func (a A) f() {
fmt.Println("hi ", a.Face)
}
func main() {
var s A = A{ Face: 9 }
s.f()
var sa Aa = Aa{ Face: 9 }
sa.f()
}
编译错误信息:sa.f undefined (type Aa has no field or method f)
通过type 关键字在原有类型基础上构造出一个新类型,我们需要针对新类型来重新创建新方法。
17.2 type 定义类型别名
type IZ = int
这种写法其实是定义了int类型的别名,类型别名在1.9中实现,可将别名类型和原类型这两个类型视为完全一致使用。type IZ int 其实是定义了新类型,这和类型别名 完全不是一个含义。自定义类型不会拥有原类型附带的方法,而别名是拥有原类型附带的。下面举2个例子说明:
如果是类型别名,完整拥有其方法:
package main
import (
"fmt"
)
type A struct {
Face int
}
type Aa=A // 类型别名
func (a A) f() {
fmt.Println("hi ", a.Face)
}
func main() {
var s A = A{Face: 9}
s.f()
var sa Aa = Aa{Face: 9}
sa.f()
}
程序输出:
hi 9
hi 9
结构化的类型没有真正的值,它使用 nil 作为默认值(在 Objective-C 中是 nil,在 Java 中是 null,在 C 和 C++ 中是NULL或 0)。值得注意的是,Go 语言中不存在类型继承。
函数也是一个确定的类型,就是以函数签名作为类型。这种类型的定义例如:
type typeFunc func ( int, int) int
我们可以在函数体中的某处返回使用类型为 typeFunc 的变量 varfunc:
return varfunc
自定义类型不会继承原有类型的方法,但接口方法或组合类型的内嵌元素则保留原有的方法。
// Mutex 用两种方法,Lock and Unlock。
type Mutex struct { /* Mutex fields */ }
func (m *Mutex) Lock() { /* Lock implementation */ }
func (m *Mutex) Unlock() { /* Unlock implementation */ }
// NewMutex和 Mutex 一样的数据结构,但是其方法是空的。
type NewMutex Mutex
// PtrMutex 的方法也是空的
type PtrMutex *Mutex
// *PrintableMutex 拥有Lock and Unlock 方法
type PrintableMutex struct {
Mutex
}
本书《Go语言四十二章经》内容在github上同步地址:https://github.com/ffhelicopter/Go42
虽然本书中例子都经过实际运行,但难免出现错误和不足之处,烦请您指出;如有建议也欢迎交流。