Golang中自定义类型


Go 允许定义新的类型,可以通过关键字 type 实现:

1
type foo int

如上我们创建了一个新的类型 foo 作用跟 int 一样。创建更加复杂的类型需要用到 struct 关键字。这有个在一个数据结构中记录某人的姓名(string)和年龄(int),并且使其成为一个新的类型的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
package main
import "fmt"

type NameAge struct {
name string // 不导出
age int // 不导出
}

func main() {
a := new(NameAge)
a.name = "Pete" ; a.age = 42
fmt.Printf("%v\n", a)
}

通常,fmt.Printf("%v\n", a) 的输出是&{Pete 42}

Go 知道如何打印结构。如果仅想打印某一个,或者某几个结构中的字段,需要使用 .。例如,仅仅打印名字:

1
fmt.Printf("%s", a.name) // %s 格式化字符串

结构字段

之前已经提到结构中的项目被称为field。没有字段的结构:struct {}

或者有四个字段的:

1
2
3
4
5
struct {
x, y int
A *[]int
F func()
}

如果省略字段的名字,可以创建匿名字段,例如:

1
2
3
4
5
6
struct {
T1 // 字段名字是 T1
*T2 // 字段名字是 T2
P.T3 // 字段名字是 T3
x, y int // 字段名字是 x 和 y
}

注意首字母大写的字段可以被导出,也就是说,在其他包中可以进行读写。字段名以小写字母开头是当前包的私有的。

方法

可以对新定义的类型创建函数以便操作,可以通过两种途径:

  1. 创建一个函数接受这个类型的参数:func doSomething(n1 *NameAge, n2 int) { /* */ }(你可能已经猜到了)这是函数调用。

  2. 创建一个工作在这个类型上的函数(参阅在 2.1 中定义的接收方):func (n1 *NameAge) doSomething(n2 int) { /* */ }这是方法调用,可以类似这样使用:

1
2
var n *NameAge
n.doSomething(2)

使用函数还是方法是由程序员决定的,但是如果想要满足接口就只能使用方法。如果没有这方面的需求,那就由个人品味决定了。下面的类型定义中有一些微小但是很重要的不同之处。

我们假设有如下代码:

1
2
3
4
5
// Mutex 数据类型有两个方法,Lock 和 Unlock。
type Mutex struct { /* Mutex 字段 */ }

func (m *Mutex) Lock() { /* Lock 实现 */ }
func (m *Mutex) Unlock() { /* Unlock 实现 */ }

现在用两种不同的风格创建了两个数据类型:

1
2
3
4
type NewMutex Mutex
type PrintableMutex struct {
Mutex
}

现在 NewMutux 等同于 Mutex,但是它没有任何 Mutex 的方法。换句话说,它的方法是空的。但是 PrintableMutex 已经从 Mutex 继承了方法集合。*PrintableMutex 的方法集合包含了 Lock 和 Unlock 方法,被绑定到其匿名字段 Mutex。


文章作者: RickDamon
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 RickDamon !
  目录