结构体方法
一个方法就是一个包含了接收者的函数。
对于结构体方法,接收者可以是结构体类型的值或是指针
结构体 = 是通过 type 结构体名 struct 定义的结构体
方法 = 函数
结构体方法= 结构体名.函数()
指针类型接收者
当接收者类型为指针时,可以通过该方法改变该接收者的成员变量值,即使你使用了非指针类型实例调用该函数,也可以改变实例对应的成员变量值
举例:
package main
import "fmt"
type User struct {
Name string
Email string
}
func (u *User) ChangeName() {
u.Name = "Tom"
}
func main() {
u := &User{"Peter", "go@go.com"} //创建指针类型结构体实例
fmt.Println(u)
u.ChangeName()
fmt.Println(u)
}
// &{Peter go@go.com}
// &{Tom go@go.com}
图解分析 :
因为在定义方法的过程中使用的是: **指针(物理地址层面)**类型接收者,所以对结构体的值进行修改是在物理空间上发生的,因此会改变实例化结构体的成员值 。
注意:
只要结构体方法的接收者为指针类型,即使实例不是指针类型,修改也能生效!
举例:
package main
import "fmt"
type User struct {
Name string
Email string
}
func (u *User) ChangeName() {
u.Name = "Tom"
}
func main() {
u := User{"Peter", "go@go.com"}
fmt.Println(u)
u.ChangeName()
fmt.Println(u)
}
// &{Peter go@go.com}
// &{Tom go@go.com}
值类型接收者
当接收者不是一个指针时,**该方法操作对应接收者值的副本(相当于在复制品层面),**否则即使你使用了指针调用函数,也无法改变成员变量值。
举例:
本次值针对上面的代码修改为 值类型接收者。
package main
import "fmt"
type User struct {
Name string
Email string
}
func (u User) ChangeName() {
u.Name = "Tom"
}
func main() {
u := User{"Peter", "go@go.com"}
fmt.Println(u)
u.ChangeName()
fmt.Println(u)
}
// {Peter go@go.com}
// {Peter go@go.com}
图解 :
因此值类型上的操作,相当于在复制品上的操作,因此原结构体的成员值保持不变。
即使,实例化的过程中,使用的是 指针类型结构体实例化的操作,但是也并没有发生改变。
举例:
package main
import "fmt"
type User struct {
Name string
Email string
}
func (u User) ChangeName() {
u.Name = "Tom"
}
func main() {
u := &User{"Peter", "go@go.com"}
fmt.Println(u)
u.ChangeName()
fmt.Println(u)
}
// {Peter go@go.com}
// {Peter go@go.com}