一 方法的声明
1 语法
func (recevier type) methodName(参数列表) (返回值列表){
方法体
return 返回值
}
2 说明
a 参数列表:表示方法的输入。
b recevier type: 表示这个方法和 type 这个类型进行绑定,或者说该方法作用于 type 类型。
c receiver type: type 可以是结构体,也可以其它的自定义类型。
d receiver: 就是 type 类型的一个变量(实例)。比如:Person 结构体的一个变量(实例)。
e 返回值列表: 表示返回的值,可以有多个。
f 方法主体: 表示为了实现某一功能代码块。
g return 语句不是必须的。
二 方法的注意事项和细节
1 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
2 如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
a 代码
package main
import "fmt"
type Circle struct {
radius float64
}
// 为了提高效率,通常方法和结构体的指针类型绑定
func (c *Circle) area2() float64 {
// 因为 c 是指针,标准的访问其字段的方式是 (*c).radius
// return 3.14 * (*c).radius * (*c).radius
// (*c).radius 等价 c.radius
fmt.Printf("c 是 *Circle,指向的地址=%p", c)
c.radius = 10
return 3.14 * c.radius * c.radius
}
func main() {
// 创建一个 Circle 变量
var c Circle
fmt.Printf("main c 结构体变量地址 =%p\n", &c)
c.radius = 7.0
// res2 := (&c).area2()
// 编译器底层做了优化 (&c).area2() 等价 c.area()
// 因为编译器会自动的给加上 &c
res2 := c.area2()
fmt.Println("面积=", res2)
fmt.Println("c.radius = ", c.radius) // 10
}
b 测试
main c 结构体变量地址 =0xc042052080
c 是 *Circle,指向的地址=0xc042052080面积= 314
c.radius = 10
c 图解
3 Golang 中的方法作用在指定的数据类型上的,和指定的数据类型绑定。因此自定义类型,都可以有方法,而不仅仅是 struct。比如 int、float32 等都可以有方法
a 代码
package main
import (
"fmt"
)
/*
Golang 中的方法作用在指定的数据类型上的,和指定的数据类型绑定。因此自定义类型,都可以有方法,而不仅仅是 struct。比如 int、float32 等都可以有方法。
*/
type integer int
func (i integer) print() {
fmt.Println("i=", i)
}
// 编写一个方法,可以改变i的值
func (i *integer) change() {
*i = *i + 1
}
func main() {
var i integer = 10
i.print()
i.change()
fmt.Println("i=", i)
}
b 测试
i= 10
i= 11
4 方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问
5 如果一个类型实现了 String()这个方法,那么 fmt.Println 默认会调用这个变量的 String()进行输出
a 代码
package main
import (
"fmt"
)
type Student struct {
Name string
Age int
}
// 给 *Student 实现方法String()
func (stu *Student) String() string {
str := fmt.Sprintf("Name=[%v] Age=[%v]", stu.Name, stu.Age)
return str
}
func main() {
// 定义一个Student变量
stu := Student{
Name: "tom",
Age: 20,
}
// 如果实现了 *Student 类型的 String方法,就会自动调用
fmt.Println(&stu)
}
b 测试
Name=[tom] Age=[20]