方法使用的深度剖析
方法的声明(定义)
func (recevier type) methodName(参数列表) (返回值列表){
方法体
return 返回值
}
- 参数列表:表示方法输入
- recevier type : 表示这个方法和 type 这个类型进行绑定,或者说该方法作用于 type 类型
- receiver type : type 可以是结构体,也可以其它的自定义类型
- receiver : 就是 type 类型的一个变量(实例)
- 返回值列表:表示返回的值,可以多个
- 方法主体:表示为了实现某一功能代码块
- return 语句不是必须的。
方法的注意事项和细节
- 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
- 如果希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
//为了提高效率,通常我们方法和结构体的指针类型绑定
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
}
- Golang 中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是 struct, 比如 int , float32 等都可以有方法
type integer int
func (i integer) print() {
fmt.Println("i=", i)
}
func main() {
var i integer = 10
i.print()
}
type integer int
func (i *integer) change() {
*i = *i + 1
}
func main() {
var i integer = 10
i.change()
fmt.Println("i=", i)
}
- 方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问。
- 如果一个类型实现了 String()这个方法,那么 fmt.Println 默认会调用这个变量的 String()进行输出
type Student struct {
Name string
Age int
}
func (stu *Student) String() string {
str := fmt.Sprintf("Name=[%v] Age=[%v]", stu.Name, stu.Age)
return str
}
func main() {
stu := Student{
Name : "tom",
Age : 20,
}
-- 如果你实现了 *Student 类型的 String方法,就会自动调用
fmt.Println(&stu)
}