• 作为函数参数,值类型就是值类型,指针类型就是指针类型
• 方法有一个值类型和指针类型的接受者时,都可以直接调用,内部会
自动进行语法的转换。
一个方法只是一个函数,它有一个特殊的接收者(receiver)类型,该接收者放在 func 关键字和函数名之间。接收者可以是结构体类型或非结构体类型。可以在方法内部访问接收者。
一般语法为:
func (t receiver_type) methodName(parameter list) {}
一、参数 receiver 类型可以是 T 或 *T。以指针为接收者也是可以的。两者的区别在于, 以*T为接收者时,方法内部对其的修改对于外部有效,而以 T作为接受者时,对于外部无效。
1func(e Employee)changeName(newName string){
2e.name = newName
3}
4func(e *Employee)changeAge(newAge int){
5e.age = newAge
6}
7emp1 := Employee{
8name: "张三",
9salary: 6000,
10currency: "$",
11age: 18,
12Address: Address{ "山东", "济南"},
13}
14emp1.displaySalary()
15
16fmt.Println( "Before call changeName ", emp1.name)
17//修改名字,未发生变化因为是值传递
18emp1.changeName( "zhangsan")
19fmt.Println( "After call changeName ", emp1.name) //After call changeName 张三
20
21fmt.Println( "Before change age", emp1.age)
22//利用指针来修改年龄
23emp1.changeAge( 50)
24fmt.Println( "After change age", emp1.age) //After change age 50
二、Go 不允许同名函数,但是同名方法可以定义在不同的类型上
1//Rectangle 代码规范
2typeRectangle struct{
3width float32
4height float32
5}
6//Circle 代码规范
7typeCircle struct{
8radius float32
9}
10func(e Employee)changeName(newName string){
11e.name = newName
12}
13func(e *Employee)changeAge(newAge int){
14e.age = newAge
15}
16funcmain(){
17//计算面积
18re := Rectangle{ 20, 30}
19c := Circle{ 40}
20//两个类型调用同名方法
21fmt.Println(re.getArea())
22fmt.Println(c.getArea())
23}
三、提阶,方法也支持提阶
1emp1 := Employee{
2name: "张三",
3salary: 6000,
4currency: "$",
5age: 18,
6Address: Address{ "山东", "济南"},
7}
8//提阶
9emp1.fullAddress() //山东 济南,提阶相当于直接访问Address里的
10emp1.Address.fullAddress() //山东 济南
四、非结构类型的方法
非结构体类型也可以定义方法,不过这里需要注意一点。为了定义某个类型的方法,接收者类型的定义与方法的定义必须在同一个包中。
非结构体类型也可以定义方法,不过这里需要注意一点。为了定义某个类型的方法,接收者类型的定义与方法的定义必须在同一个包中。
因为必须在一个包中而int则在main包中我们没法去定义这个里为了简单直观,给int声明了别名
1//非结构体方法扩展
2typemyInt int
3
4func(a myInt)add(b myInt)myInt{
5returna + b
6}
7funcmain(){
8//调用扩展的方法
9num1 := myInt( 5)
10num2 := myInt( 10)
11sum := num1.add(num2)
12fmt.Println( "Sum is", sum)
13
14}
下面附上完整实例程序
1packagemain
2
3import(
4"fmt"
5"math"
6)
7
8//Employee 需要添加注释或者改成非导出变量(首字母小写)
9typeEmployee struct{
10name string
11currency string
12salary int
13age int
14Address
15}
16
17//Address 代码规范
18typeAddress struct{
19city string
20state string
21}
22
23//Rectangle 代码规范
24typeRectangle struct{
25width float32
26height float32
27}
28
29//Circle 代码规范
30typeCircle struct{
31radius float32
32}
33
34//Employee 的方法
35func(e Employee)displaySalary(){
36fmt.Println(e)
37}
38func(e Employee)changeName(newName string){
39e.name = newName
40}
41func(e *Employee)changeAge(newAge int){
42e.age = newAge
43}
44
45//Address 的方法
46func(add Address)fullAddress(){
47fmt.Println(add.city, add.state)
48}
49
50//Rectangle 的方法计算面积
51func(r Rectangle)getArea()float32{
52returnr.width * r.height
53}
54
55//Circle 的方法
56func(c Circle)getArea()float32{
57returnmath.Pi * c.radius * c.radius
58}
59
60//非结构体方法扩展
61typemyInt int
62
63func(a myInt)add(b myInt)myInt{
64returna + b
65}
66funcmain(){
67//调用方法
68emp1 := Employee{
69name: "张三",
70salary: 6000,
71currency: "$",
72age: 18,
73Address: Address{ "山东", "济南"},
74}
75emp1.displaySalary()
76
77fmt.Println( "Before call changeName ", emp1.name)
78//修改名字,未发生变化因为是值传递
79emp1.changeName( "zhangsan")
80fmt.Println( "After call changeName ", emp1.name) //After call changeName 张三
81
82fmt.Println( "Before change age", emp1.age)
83//利用指针来修改年龄
84emp1.changeAge( 50)
85fmt.Println( "After change age", emp1.age) //After change age 50
86
87//提阶
88emp1.fullAddress() //山东 济南,提阶相当于直接访问Address里的
89emp1.Address.fullAddress() //山东 济南
90
91//计算面积
92re := Rectangle{ 20, 30}
93c := Circle{ 40}
94//两个类型调用同名方法
95fmt.Println(re.getArea())
96fmt.Println(c.getArea())
97
98//调用扩展的方法
99num1 := myInt( 5)
100num2 := myInt( 10)
101sum := num1.add(num2)
102fmt.Println( "Sum is", sum)
103
104}
ID:Golangweb