原文作者:学生黄哲 链接:https://www.jianshu.com/p/6e615b08cfaf 來源:简书 简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
• 只能为当前包内命名类型定义⽅法。 • 参数 receiver 可任意命名。如⽅法中未曾使⽤,可省略参数名。 • 参数 receiver 类型可以是 T 或 *T。基类型 T 不能是接⼝或指针。 • 不⽀持⽅法重载, receiver 只是参数签名的组成部分。 • 可⽤实例 value 或 pointer 调⽤全部⽅法,编译器⾃动转换。 • Go 不允许同名函数,但是同名方法可以定义在不同的类型上 • method和receiver必须在同一个包里定义 • 作为函数参数,值类型就是值类型,指针类型就是指针类型 • 方法有一个值类型和指针类型的接受者时,都可以直接调用,内部会 自动进行语法的转换。
一个方法只是一个函数,它有一个特殊的接收者(receiver)类型,该接收者放在 func 关键字和函数名之间。接收者可以是结构体类型或非结构体类型。可以在方法内部访问接收者。 一般语法为:
func (t receiver_type) methodName(parameter list) {}
1func (e Employee) changeName(newName string) {
2 e.name = newName
3}
4func (e *Employee) changeAge(newAge int) {
5 e.age = newAge
6}
7 emp1 := Employee{
8 name: "张三",
9 salary: 6000,
10 currency: "$",
11 age: 18,
12 Address: Address{"山东", "济南"},
13 }
14 emp1.displaySalary()
15
16 fmt.Println("Before call changeName ", emp1.name)
17 //修改名字,未发生变化因为是值传递
18 emp1.changeName("zhangsan")
19 fmt.Println("After call changeName ", emp1.name) //After call changeName 张三
20
21 fmt.Println("Before change age", emp1.age)
22 //利用指针来修改年龄
23 emp1.changeAge(50)
24 fmt.Println("After change age", emp1.age) //After change age 50
1//Rectangle 代码规范
2type Rectangle struct {
3 width float32
4 height float32
5}
6//Circle 代码规范
7type Circle struct {
8 radius float32
9}
10func (e Employee) changeName(newName string) {
11 e.name = newName
12}
13func (e *Employee) changeAge(newAge int) {
14 e.age = newAge
15}
16func main() {
17 //计算面积
18 re := Rectangle{20, 30}
19 c := Circle{40}
20 //两个类型调用同名方法
21 fmt.Println(re.getArea())
22 fmt.Println(c.getArea())
23}
1emp1 := Employee{
2 name: "张三",
3 salary: 6000,
4 currency: "$",
5 age: 18,
6 Address: Address{"山东", "济南"},
7 }
8 //提阶
9 emp1.fullAddress() //山东 济南,提阶相当于直接访问Address里的
10 emp1.Address.fullAddress() //山东 济南
非结构体类型也可以定义方法,不过这里需要注意一点。为了定义某个类型的方法,接收者类型的定义与方法的定义必须在同一个包中。
因为必须在一个包中而int则在main包中我们没法去定义这个里为了简单直观,给int声明了别名
1//非结构体方法扩展
2type myInt int
3
4func (a myInt) add(b myInt) myInt {
5 return a + b
6}
7func main() {
8 //调用扩展的方法
9 num1 := myInt(5)
10 num2 := myInt(10)
11 sum := num1.add(num2)
12 fmt.Println("Sum is", sum)
13
14}
1package main
2
3import (
4 "fmt"
5 "math"
6)
7
8//Employee 需要添加注释或者改成非导出变量(首字母小写)
9type Employee struct {
10 name string
11 currency string
12 salary int
13 age int
14 Address
15}
16
17//Address 代码规范
18type Address struct {
19 city string
20 state string
21}
22
23//Rectangle 代码规范
24type Rectangle struct {
25 width float32
26 height float32
27}
28
29//Circle 代码规范
30type Circle struct {
31 radius float32
32}
33
34//Employee 的方法
35func (e Employee) displaySalary() {
36 fmt.Println(e)
37}
38func (e Employee) changeName(newName string) {
39 e.name = newName
40}
41func (e *Employee) changeAge(newAge int) {
42 e.age = newAge
43}
44
45//Address 的方法
46func (add Address) fullAddress() {
47 fmt.Println(add.city, add.state)
48}
49
50//Rectangle 的方法计算面积
51func (r Rectangle) getArea() float32 {
52 return r.width * r.height
53}
54
55//Circle 的方法
56func (c Circle) getArea() float32 {
57 return math.Pi * c.radius * c.radius
58}
59
60//非结构体方法扩展
61type myInt int
62
63func (a myInt) add(b myInt) myInt {
64 return a + b
65}
66func main() {
67 //调用方法
68 emp1 := Employee{
69 name: "张三",
70 salary: 6000,
71 currency: "$",
72 age: 18,
73 Address: Address{"山东", "济南"},
74 }
75 emp1.displaySalary()
76
77 fmt.Println("Before call changeName ", emp1.name)
78 //修改名字,未发生变化因为是值传递
79 emp1.changeName("zhangsan")
80 fmt.Println("After call changeName ", emp1.name) //After call changeName 张三
81
82 fmt.Println("Before change age", emp1.age)
83 //利用指针来修改年龄
84 emp1.changeAge(50)
85 fmt.Println("After change age", emp1.age) //After change age 50
86
87 //提阶
88 emp1.fullAddress() //山东 济南,提阶相当于直接访问Address里的
89 emp1.Address.fullAddress() //山东 济南
90
91 //计算面积
92 re := Rectangle{20, 30}
93 c := Circle{40}
94 //两个类型调用同名方法
95 fmt.Println(re.getArea())
96 fmt.Println(c.getArea())
97
98 //调用扩展的方法
99 num1 := myInt(5)
100 num2 := myInt(10)
101 sum := num1.add(num2)
102 fmt.Println("Sum is", sum)
103
104}
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。