Go语言中,其实方法就是一种特殊的函数,相对于普通函数,方法多了一个接收者。方法其实就是和这个接收者进行捆绑的,捆绑之后,这个方法就变成了接收者的一个属性。
1.方法的格式
func (receiver type) f([param type]) [type]{
//code
}
example (以结构体为例,接收者还可以是别的数据类型):
type Person struct{
Name string
Age int
}
func (p Person) info() string {
return p.Name
}
func main(){
p := Person{
"Liu三变",
26,
}
fmt.Println(p.info())
}
##输出:
Liu三变
2.到底是绑定数值还是绑定指针?
今天讨论的重点是:方法中接收者既可以是数值也可以是指针,到底是绑定什么呢?我看网上不少人说绑定指针和数值是效果是一样的,这种说法其实是不对的。
我们再回归到方法的定义中,方法说到底就是一种特殊的函数function
,另外这个将这个函数的功能和对应的接收者绑定,使得这个function
变成接收者的一个属性,如果是数值,就意味着和数值绑定,如果是指针,就意味着和指针绑定。再者,别忘了,方法也是一个function
,既然是函数,可以选择传参的吧。
1)在不传入参数的情况下,里面涉及到的变量其实就一个,改变这个变量,不管是改变数值还是指针,效果是一样的。
2)如果选择传入参数,此时就涉及到多个变量,多变量的情况下,就涉及到数值和指针的影响。
3.例子
具体是怎样的,我们代码见。
Info1绑定数值,Info2绑定指针:
package main
import(
"fmt"
)
type Person struct{
Name string
Age int
}
func (p1 Person) Info1(n string) string{
p1.Name = n
return p1.Name
}
func (p2 *Person) Info2(n string)string{
p2.Name = n
return p2.Name
}
func main(){
man1 := Person{
"Liu三变",
26,
}
man2 := Person{
"Hero",
30,
}
fmt.Println(man1.Name)
fmt.Println(man2.Name)
man1.Info1("鸣人")
man2.Info2("佐助")
fmt.Println(man1.Name)
fmt.Println(man2.Name)
}
运行结果:
Liu三变
Hero
Liu三变
佐助
此时会发现:绑定了指针的对象才会发生变化,单纯绑定数值的,原来对象并不会发生改变。
4.通过地址查看
package main
import(
"fmt"
"unsafe"
)
type Person struct{
Name string
Age int
}
func (p1 Person) Info1(n string) string{
p1.Name = n
fmt.Printf("p1 address is %x\n",unsafe.Pointer(&p1.Name))
return p1.Name
}
func (p2 *Person) Info2(n string)string{
p2.Name = n
fmt.Printf("p2 address is %x\n",unsafe.Pointer(&p2.Name))
return p2.Name
}
func main(){
man1 := Person{
"Liu三变",
26,
}
man2 := Person{
"Hero",
30,
}
fmt.Println(man1.Name)
fmt.Println(man2.Name)
man1.Info1("鸣人")
fmt.Printf("p1 address is %x\n",unsafe.Pointer(&man1.Name))
man2.Info2("佐助")
fmt.Printf("p2 address is %x\n",unsafe.Pointer(&man2.Name))
fmt.Println(man1.Name)
fmt.Println(man2.Name)
}
运行结果:
Liu三变
Hero
p1 address is c00000c0a0
p1 address is c00000c060
p2 address is c00000c080
p2 address is c00000c080
Liu三变
佐助
由以上测试看出:采用数值绑定(第一种)会产生内存拷贝
实践出真知,实践才是检验真理的唯一标准