方法
基本介绍
在某些情况下,我们要需要声明(定义)方法。比如 Person 结构体:除了有一些字段外( 年龄,姓名…),Person 结构体还有一些行为比如:可以说话、跑步…,通过学习,还可以做算术题。这时就要用方法 才能完成。
Golang 中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型, 都可以有方法,而不仅仅是 struct。
方法的声明和调用
type A struct {
Num int
}
func (a A) test() { f
mt.Println(a.Num)
}
对上面的语法的说明
- func (a A) test() {} 表示 A 结构体有一方法,方法名为 test
- (a A) 体现 test 方法是和 A 类型绑定的
举例说明
对上面的总结
-
test 方法和 Person 类型绑定
-
test 方法只能通过 Person 类型的变量来调用,而不能直接调用,也不能使用其它类型变量来调用
-
func (p Person) test() {}… p 表示哪个 Person 变量调用,这个 p 就是它的副本, 这点和函数传参非 常相似。
-
p 这个名字,有程序员指定,不是固定, 比如修改成 person 也是可以
方法快速入门
-
给 Person 结构体添加 speak 方法,输出 xxx 是一个好人
-
给 Person 结构体添加 jisuan 方法,可以计算从 1+…+1000 的结果, 说明方法体内可以函数一样, 进行各种运算
-
给 Person 结构体 jisuan2 方法,该方法可以接收一个数 n,计算从 1+…+n 的结果
-
给 Person 结构体添加 getSum 方法,可以计算两个数的和,并返回结果
-
方法的调用
方法的调用和传参机制原理:(重要!)
说明: 方法的调用和传参机制和函数基本一样,不一样的地方是方法调用时,会将调用方法的变量,当做实参也传递给方法。下面我们举例说明。
- 案例 1:
画出前面 getSum 方法的执行过程+说明
说明:
- 在通过一个变量去调用方法时,其调用机制和函数一样
- 不一样的地方时,变量调用方法时,该变量本身也会作为一个参数传递到方法(如果变量是值类 型,则进行值拷贝,如果变量是引用类型,则进行地址拷贝)
- 案例 2
请编写一个程序,要求如下:
- 声明一个结构体 Circle, 字段为 radius
- 声明一个方法 area 和 Circle 绑定,可以返回面积。
- 提示:画出 area 执行过程+说明
方法的声明(定义)
func (recevier type) methodName(参数列表) (返回值列表){
方法体
return 返回值
}
- 参数列表:表示方法输入
- recevier type : 表示这个方法和 type 这个类型进行绑定,或者说该方法作用于 type 类型
- receiver type : type 可以是结构体,也可以其它的自定义类型
- receiver : 就是 type 类型的一个变量(实例),比如 :Person 结构体 的一个变量(实例)
- 返回值列表:表示返回的值,可以多个
- 方法主体:表示为了实现某一功能代码块
- return 语句不是必须的。
方法的注意事项和细节
- 结构体类型是值类型,在方法调用中,遵守值类型的传递机制,是值拷贝传递方式
- 如程序员希望在方法中,修改结构体变量的值,可以通过结构体指针的方式来处理
- Golang 中的方法作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型, 都可以有方法,而不仅仅是 struct, 比如 int , float32 等都可以有方法
- 方法的访问范围控制的规则,和函数一样。方法名首字母小写,只能在本包访问,方法首字母 大写,可以在本包和其它包访问。
- 如果一个类型实现了 String()这个方法,那么 fmt.Println 默认会调用这个变量的 String()进行输出
方法和函数区别
-
调用方式不一样
函数的调用方式: 函数名(实参列表) 方法的调用方式: 变量.方法名(实参列表) -
对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
-
对于方法(如 struct 的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反 过来同样也可以
总结: -
不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和哪个类型绑定.
-
如果是和值类型,比如 (p Person) , 则是值拷贝, 如果和指针类型,比如是 (p *Person) 则 是地址拷贝。
面向对象例题
学生案例:
- 编写一个 Student 结构体,包含 name、gender、age、id、score 字段,分别为 string、string、int、 int、float64 类型。
- 结构体中声明一个 say 方法,返回 string 类型,方法返回信息中包含所有字段值。
- 在 main 方法中,创建 Student 结构体实例(变量),并访问 say 方法,并将调用结果打印输出。
package main
import (
"fmt"
)
type Student struct{
name string
gender string
age int
id int
score float64
}
func (student *Student) say() string{
infoStr := fmt.Sprintf("student 的信息 name=[%v] gender=[%v], age=[%v] id=[%v] score=[%v]",
student.name, student.gender, student.age, student.id, student.score)
return infoStr
}
func main() {
//测试
//创建一个 Student 实例变量
var stu = Student{ name : "tom", gender : "male", age : 18,
id : 1000,
score : 99.98,
}
fmt.Println(stu.say())
}
创建结构体变量时指定字段值
说明
Golang 在创建结构体实例(变量)时,可以直接指定字段的值
- 方式 1
- 方式 2