方法和函数区别
调用方式不一样
函数的调用方式:
函数名(实参列表)
方法的调用方式:
变量.方法名(实参列表)
对于普通函数,接收者为值类型时,不能将指针类型的数据直接传递,反之亦然
type Person struct {
Name string
}
func test01(p Person) {
fmt.Println(p.Name)
}
func main() {
p := Person{"tom"}
test01(p)
-- test01(&p) 错误,是值类型,不能传地址
}
输出结果:
如果是参数是指针类型,则只能传指针
type Person struct {
Name string
}
func test01(p *Person) {
fmt.Println(p.Name)
}
func main() {
p := Person{"tom"}
test01(&p)
-- test01(p) 错误,是指针类型,不能传值
}
对于方法(如 struct 的方法),接收者为值类型时,可以直接用指针类型的变量调用方法,反过来同样也可以
type Person struct {
Name string
}
func (p Person) test03() {
p.Name = "jack"
fmt.Println("test03() =", p.Name)
}
func main() {
p := Person{"tom"}
p.test03()
fmt.Println("main() p.name=", p.Name) // tom
(&p).test03() // 从形式上是传入地址,但是本质仍然是值拷贝
fmt.Println("main() p.name=", p.Name) // tom
}
输出结果:
注意:(&p).test03() 从形式上是传入地址,但是本质仍然是值拷贝
type Person struct {
Name string
}
func (p *Person) test04() {
p.Name = "mary"
fmt.Println("test03() =", p.Name) // mary
}
func main() {
p := Person{"tom"}
(&p).test04()
fmt.Println("main() p.name=", p.Name) // mary
p.test04() // 等价 (&p).test04 , 从形式上是传入值类型,但是本质仍然是地址拷贝
}
输出结果:
注意:p.test04() 等价 (&p).test04 , 从形式上是传入值类型,但是本质仍然是地址拷贝
总结:
不管调用形式如何,真正决定是值拷贝还是地址拷贝,看这个方法是和哪个类型绑定.
如果是和值类型,比如 (p Person) , 则是值拷贝如果和指针类型,比如是 (p *Person) 则是地址拷贝。