1.取结构体的地址实例化
- 使用&对结构体进行取缔值操作相当于对该结构体类型进行了一次new实例化操作
package main
import "fmt"
type student struct {
name string
age int
}
func main() {
stu := &student{}
fmt.Printf("stu=%v\n",stu) //stu=&{ 0}
stu.name="ben"
stu.age=18
fmt.Printf("stu=%v\n",stu) //stu=&{ben 18}
fmt.Println(stu.age) //18
}
- stu.name="ben"其实在底层是(*stu).name=“ben”,这是go语言实现的语法糖
2.构造函数
- go语言的结构体并没有构造函数,但是可以自己实现
- 实现了一个newstudent的构造函数。因为strcut是值类型,如果结构体比较复杂的话,值拷贝性能开销会比较大,所以该构造函数返回的是结构体指针类型
package main
import "fmt"
type student struct {
name string
age int
}
func newstudent(new_name string,new_age int) *student {
return &student{
name:new_name,
age:new_age,
}
}
func main() {
stu := newstudent("ben",18)
fmt.Printf("%v\n",stu) //&{ben 18}
fmt.Println(stu.name,stu.age) //ben 18
}
3.指针类型接受值
- 指针类型的接收者由一个结构体的指针组成,由于指针的特性,调用方法时修改接收者指针的任意成员变量,在方法结束后,修改都是有效的。这种方式就十分接近于其他语言中面向对象的this或者self
package main
import "fmt"
type person struct {
name string
age int
}
func (p *person)setage(newage int) {
p.age = newage
}
func newperson(name string,age int)*person {
return &person{
name: name,
age: age,
}
}
func main() {
p1:=newperson("ben",18)
fmt.Println(p1.age) //18
p1.setage(5)
fmt.Println(p1.age) //5
}
4.值类型的接收者
- 当方法作用于值类型接收者时,go语言会在代码运行时将接收者的值复制一份。在值类型接收者的方法中可以获取接收者的成员值,但是修改操作只是针对副本,无法修改接收者变量本身
package main
import "fmt"
type person struct {
name string
age int
}
func (p person)setage(newage int) {
p.age = newage
}
func newperson(name string,age int)*person {
return &person{
name: name,
age: age,
}
}
func main() {
p1:=newperson("ben",18)
fmt.Println(p1.age) //18
p1.setage(5)
fmt.Println(p1.age) //18
}
什么时候需要使用指针类型接收者
- 需要修改接收者中的值
- 接收者说拷贝代价比较大的大对象
- 保证一致性,如果有某个方法使用了指针接收者,那么其他的方法也应该使用指针接收者