持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第38天,点击查看活动详情
一、方法使用深度解析
1.1 方法的声明(定义)
func (recevier type) methodName (参数列表) (返回值列表){
方法体
return 返回值
}
- 参数列表:表示方法输入
- recevier type :表示这个方法和type这个类型进行绑定,或者说该方法作用于type类型
- receiver type : type可以是结构体,也可以其它的自定义类型
- receiver :就是type类型的一个变量(实例),比如: Person结构体 的一个变量(实例)
- 参数列表:表示方法输入
- 返回值列表:表示返回的值,可以多个
- 方法主体:表示为了实现某-功能代码块
- return语句不是必须的。
1.2 注意事项
- 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
- 如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理。详见案例 2.1 案例一
- Golang中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是struct,比如int,float32等都可以有方法. 详见案例 2.2 案例二
- 方法的访问范围控制的规则,和函数-样。方法名首字母小写,只能在本包访问,方法首字母大写,可以在本包和其它包访问。
- 如果一个类型实现了String()这个方法,那么fmt.Println默认会调用这个变量的String()进行输出,如果没有实现,&取的就是地址.详见 2.3 案例三
二 案例分析
2.1 案例一
package main
import (
"fmt"
)
// 1. 声明一个结构体Circle.字段为 radius
// 2. 声明一个方法area和Circle绑定,可以返回面积
type Circle struct {
radius float64
}
func (c Circle) area() float64 {
return 3.14 * c.radius * c.radius
}
// 为了提高效率,通常方法和结构体的指针类型进行绑定
func (c *Circle) area2() float64 {
// 因为 c 是指针,标准访问字段方式 如下 (*c).radius
// 这里也可以写成 c.radius ,在之前有讲过,底层进行优化,方便程序员进行编写
return 3.14 * (*c).radius * (*c).radius
}
func main() {
// // 创建实例
// c := Circle{}
// c.radius = 3.14
// // 3.14 的圆的面积是 30.959144000000002
// fmt.Printf("%v 的圆的面积是 %v\n", c.radius, c.area())
// 指针类型绑定调用
c := Circle{}
c.radius = 5.0
prtResult := (&c).area2()
// 编译器底层做了优化,也可以这样写
// (&c).area2() =======>>> c.area2()
// 编译器自动加上
// prtResult = 78.5
fmt.Println("prtResult = ", prtResult)
}
2.2 案例二
package main
import "fmt"
/* Golang中的方法作用在指定的数据类型上的(即:
和指定的数据类型绑定),因此自定义类型,都可以有方法,
而不仅仅是struct,比如int,float32等都可以有方法.
*/
type integer int
func (i integer) print() {
fmt.Println("print() = ", i)
}
// 编写一个方法,可以修改i的值
func (i *integer) change() {
*i += 1
}
func main() {
var i integer = 10
// i = 10
i.print()
// 调用change方法
i.change()
// print() = 11
i.print()
// main i= 11
fmt.Println("main i= ", i)
}
2.3 案例三
package main
import "fmt"
// 定义结构体
type Student struct {
Name string
Age int
}
// 给 *student 实现方法String()
func (student *Student) String() string {
str := fmt.Sprintf("Name = [%v], Age=[%v]", student.Name, student.Age)
return str
}
func main() {
// 调用 student的String方法
stu := Student{"Aliy", 22}
// Main() stu = Name = [Aliy], Age=[22]
fmt.Println("Main() stu = ", &stu)
}