go学习笔记(2) — method

go的方法类让我这位php受害者难受的要死 , 但是学习了一段时间之后,不得不说,go的类方法是真的牛批。不扯谈了,开始写文章。

method

Go 中可以把函数当作struct的字段一样处理,带有接收者的函数,成为method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package main

import "fmt"

const (
MALE = iota
FEMALE
)

type age int

type human struct {
name string
age
gender int
}

type humanList []human

type student struct {
human
class string
}

type teacher struct {
human
school string
}

func gender(g int) string {
if g == 0 {
return "male"
}
return "Female"
}

func (h *human) setAge(y int) {
h.age = age(y)
fmt.Printf("this people name %s is age %v is a %s \n", h.name, h.age, gender(h.gender))
}

func (t *teacher) setAge(y int) {
t.age = age(y)
fmt.Printf("this teacher name %s is age %v is a %s\n", t.name, t.age, gender(t.gender))
}


func main() {
hl := humanList{
human{"jack", 18, MALE},
}
hl[0].setAge(20)

t := teacher{human{"jack", 18, MALE}, "school"}
t.setAge(21)
s := student{human{"jack", 18, MALE}, "class"}
s.setAge(22)
}

这道程序的输出为

1
2
3
this people name jack is age 20 is a male 
this teacher name jack is age 21 is a male
this people name Marry is age 22 is a Female

上面案例基本包含了method 的用法了

在go中,继承的实现非常的简单粗暴, 如下

1
2
3
4
5
6
7
8
9
type human struct {
name string
age
gender int
}
type student struct {
human
class string
}

直接把需要继承的父结构体包含进去就能使用父结构体的所有method了

而如果需要当多个结构体中,单个结构体想要重写父结构体的同名method的话,只需要

1
2
3
4
5
6
7
8
9
func (h *human) setAge(y int) {
h.age = age(y)
fmt.Printf("this people name %s is age %v is a %s \n", h.name, h.age, gender(h.gender))
}

func (t *teacher) setAge(y int) {
t.age = age(y)
fmt.Printf("this teacher name %s is age %v is a %s\n", t.name, t.age, gender(t.gender))
}

不得不说真tm的简单粗暴……

我们发现,写 setAge 方法时,前面的 receiver 使用了指向 human 的指针,这是因为如果传入的是 human而不是*human的话,我们的方法操作对象将不是对human本身的引用,而是对human所传入的值进行修改 。

而当你使用 *human 的时候,在方法内并不需要*h 来进行修改,因为 go 判断你是要去修改指针所获取的值,在看资料的时候资料说加不加 *都可以,但我实际操作的时候发现加了*的话编译是不通过的,或许是go的版本问题吧。不过 hl[0].setAge(20) 这个写成 (&hl[0]).setAge(20) 倒是可以 ,这是go自动转换的机制。