基本介绍
- 在某些情况下,我们需要声明(定义)方法。比如
Person结构体
:除了有一些字段外(年龄
,姓名
..),Person
结构体还有一些行为比如:说话、跑步、学习做算术题
。这时就要用方法才能完成
。
Golang中的
方法是作用在指定的数据类型上
的(即:和指定的数据类型绑定
),因些自定义类型都有方法
而不仅仅是struct
方法的声明和调用
type A struct {
Num int
}
func (a A) test() {
fmt.Println(a.Num)
}
对上面语法的说明
1、func (a A)test( ){ }
表示A
结构体有一方法,方法名为test
2、(a A)
体现 test
方法是和A
类型绑定的
举例说明
//定义结构体
type Person struct {
Name string
}
//给Person类型绑定一个test方法
func (p Person) test() {
fmt.Println("test() name =", p.Name)
}
func main() {
var p Person
p.Name = "tom"
p.test() //调用方法
}
对上面的总结说明:
1、test方法
和Person类型
绑定
2、test方法
只能通过Person类型
的变量调用
,而不能直接调用,也不能使用其它类型的变量来调用。
3、func (p Person)test(){}
中的p
表示哪个Person
变量调用,这个p
就是它的副本,这点和函数传参非常相似。
4、p
这个形参名
是可以自定义的,不是固定的。
方法的快速入门
1、给Person
结构体加一个speak
方法,输出xxx是一个好人
//定义结构体
type Person struct {
Name string
}
func (p Person) speak() {
fmt.Println(p.Name, "是一个goodman~")
}
//给Person类型绑定一个test方法
func (p Person) test() {
fmt.Println("test() name =", p.Name)
}
func main() {
var p Person
p.Name = "tom"
p.test() //调用方法
p.speak() //调用speak方法
}
2、给Person结构体添加一个jisuan
计算方法,可以计算从 1 + ... + 1000
的结果
//定义结构体
type Person struct {
Name string
}
//给Person绑定jisuan方法
func (p Person) jisuan() {
res := 0
for i := 1; i <= 1000; i++ {
res += i
}
fmt.Println(p.Name, "计算的结果是:", res)
}
func main() {
var p Person
p.Name = "tom"
p.jisuan() //调用speak方法
}
3、给Person结构体添加一个jisuan2
计算方法,该方法可以接收一个数n
,可以计算从 1 + ... + n
的结果
//定义结构体
type Person struct {
Name string
}
//给Person绑定jisuan方法
func (p Person) jisuan(n int) {
res := 0
for i := 1; i <= n; i++ {
res += i
}
fmt.Println(p.Name, "计算的结果是:", res)
}
func main() {
var p Person
p.Name = "tom"
p.jisuan(800) //调用speak方法
}
4、给Person
结构体添加getSum
方法,返回两个数的合
//定义结构体
type Person struct {
Name string
}
//给Person绑定getSum方法
func (p Person) getSum(n1 int, n2 int) int {
return n1 + n2
}
func main() {
var p Person
p.Name = "tom"
res := p.getSum(14, 16) //调用getSum方法
fmt.Println("res=", res)
}
-
内存分析图
说明
1、在通过一个变量去调用方法时,其调用机制和函数一样
2、不一样的地方是,变量调用方法时,该变量本身也会作为一个参数传递到方法(如果变量是值类型,则进行值拷贝,如果变量是引用类型,则进行地址拷贝) 案例:计算圆的面积
package main
import "fmt"
type Circle struct {
radius float64
}
func (c Circle) area()float64{
return 3.14 * c.radius * c.radius
}
func main() {
var c Circle
c.radius = 4.0
res := c.area()
fmt.Println("面积是=",res)
}
内存图例
当area栈return后,area栈会销毁了,main栈执行完毕后,main栈也会销毁
- 通常值拷贝,效率会低一点。优化的方案是,用指针(做地址拷贝,直接指向main栈)
func (c *Circle) area()float64{
return 3.14 * c.radius * c.radius
}