Golang 方法
一、基本介绍
在某些情况下,我们要需要声明(定义)方法。比如 Person 结构体:除了有一些字段外( 年龄,姓名…),Person 结构体还有一些行为比如:可以说话、跑步…,通过学习,还可以做算术题。这时就要用方法
才能完成。
Golang 中的方法是作用在指定的数据类型上的(即:和指定的数据类型绑定),因此自定义类型,都可以有方法,而不仅仅是 struct
二、方法的声明和调用
type Person struct {
Name string
Age int
}
func (p Person) hello() {
fmt.Printf("hello ! my name is %v",p.Name)
}
func main() {
var p Person
p.Name="jerry"
p.Age=55
p.hello()
}
- func (p Person) hello() {} 表示 Person 结构体有一方法,方法名为 hello
- (p Person) 体现 hello方法是和 Person 类型绑定的
- hello方法和 Person 类型绑定
- hello方法只能通过 Person 类型的变量来调用,而不能直接调用,也不能使用其它类型变量来调
用 - func (p Person) hello() {}… p 表示哪个 Person 变量调用,这个 p 就是它的副本, 这点和函数传参非
常相似 - p 这个名字,有程序员指定,不是固定, 比如修改成 person 也是可以
三、方法快速入门
1) 简单方法
给 Person 结构体添加 speak 方法,输出 xxx 是一个好人
func (p Person) speak() {
fmt.Printf("%v 是一个好人!",p.Name)
}
2) 带有逻辑的方法
给 Person 结构体添加 calc 方法,可以计算从 1+…+1000 的结果, 说明方法体内可以函数一样,
进行各种运算
func (p Person) calc() {
sum := 0
for i:=0;i<1000;i++{
sum+=i
}
fmt.Printf("the result id %d",sum)
}
3) 带有参数的方法
给 Person 结构体 calc1 方法,该方法可以接收一个数 n,计算从 1+…+n 的结果
func (p Person) calc1(n int) {
sum := 0
for i:=0;i<n;i++{
sum+=i
}
fmt.Printf("the result id %d",sum)
}
4) 带有返回值的方法
给 Person 结构体添加 getSum 方法,可以计算两个数的和,并返回结果
func (p Person) getSum(a int, b int) int {
return a + b
}
也可以写成
func (p Person) getSum(a int, b int) (c int) {
c = a + b
return
}
注意 不能返回局部变量
的地址值
;因为函数调用结束,栈帧释放,局部变量的地址,不再受系统保护,随时可能分配给其他程序。可以返回局部变量
的值
5) 方法的调用
func main() {
var p1 Person
p1.Name = "jerry"
p1.Age = 55
p1.hello()
p1.speak()
p1.calc1(1000)
p1.calc()
p1.getSum(1,1)
}
四、方法的声明(定义)
func (recevier type) methodName(参数列表) (返回值列表){
方法体
return 返回值
}
- 参数列表:表示方法输入
- recevier type : 表示这个方法和 type 这个类型进行绑定,或者说该方法作用于 type 类型
- receiver type : type 可以是结构体,也可以其它的自定义类型
- receiver : 就是 type 类型的一个变量(实例),比如 :Person 结构体 的一个变量(实例)
- 返回值列表:表示返回的值,可以多个
- 方法主体:表示为了实现某一功能代码块
- return 语句不是必须的。
四、方法与函数的区别
方法的调用和传参机制和函数基本一样,不一样的地方是方法调用时,会将调用方法的变量,当做
实参也传递给方法。方法也体现了封装性,将需要的参数传递给指定对象,即可通过对象方法获取对应的结果
,下面我们举例说明。
type Circle struct {
R float64
}
func (c Circle)getArea() float64 {
return math.Pi * math.Pow(c.R,2)
}
func main() {
var c = Circle{R: 2}
area := c.getArea()
fmt.Printf("面积:%v",area)
}
- 调用方式不一样
函数的调用方式: 函数名(实参列表)
方法的调用方式: 变量.方法名(实参列表) - 对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
- 对于方法(如 struct 的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反
过来同样也可以