go语言中的结构体:
结构体是值传递类型:
go语言中类型分类
- 值类型:int,float,bool,string,array,struct
- 引用类型:slice,map,function,pointer
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
p1 := Person{name:"zhangsan", age:30}
fmt.Println(p1) // {zhangsan 30}
fmt.Printf("%p,%T\n", &p1,p1) // 0x3842dd3, main.Person
p2:=p1
fmt.Println(p2) // {zhangsan 30}
fmt.Printf("%p,%T\n", &p2,p2) // 0x38dfsd3, main.Person
p2.name = "lisi"
fmt.Println(p2) // {lisi 30}
fmt.Println(p1) // {zhangsan 30}
}
结构体指针(浅拷贝):
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
p1 := Person{name:"zhangsan", age:30}
fmt.Println(p1) // {zhangsan 30}
fmt.Printf("%p,%T\n", &p1,p1) // 0x3842dd3, main.Person
// 定义结构体指针
var p3 *Person
p3 = &p1
fmt.Println(p3) // &{zhangsan 30}
fmt.Printf("%p,%T\n", &p3,p3) // 0x38ds4dd3, main.Person
fmt.Println(*p3) // {zhangsan 30}
(*p3).name = "wangwu"
// p3.name = "wangwu" // 简写
fmt.Println(*p3) // {wangwu 30}
fmt.Println(p1) // {wangwu 30}
}
new函数与make函数:
- new()用于各种类型的内存分配,new(T)分配了零值填充的T类型的内存空间,并返回其地址,即一个*T类型的值,它返回了一个指针,指向新分配的类型T的零值。
- make(T,args)只能创建slice,map和channel,并且返回一个有初始值(非零)的T类型,而不是*T。对于slice,map和channel来说,make初始化了内部的数据结构,填充适当的值。
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
p1 := Person{name:"zhangsan", age:30}
fmt.Println(p1) // {zhangsan 30}
fmt.Printf("%p,%T\n", &p1,p1) // 0x3842dd3, main.Person
// new()函数
p4 := new(Person)
fmt.Printf("%p,%T\n", &p4,p4) // 0x38d42d55d3, *main.Person
fmt.Println(p4) // { 0}
// (*p4).name = "aaa"
p4.name = "aaa"
p4.age = 33
fmt.Println(*p4) // {aaa 33}
}
匿名结构体:
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
s2 := struct {
name string
age int
}{
name: "zhangsan",
age:23,
}
fmt.Println(s2) // {zhangsan 23}
}
匿名结构体,提升字段:
当结构体中定义的字段为另一个结构体,且这个字段是匿名字段时,访问数据时可以省略匿名结构体名。相当于模拟其他语言中的继承关系
package main
import "fmt"
type Book struct {
bookName string
price float64
}
type Student struct {
Book // 匿名字段
name string
age int
}
func main() {
s2 := Student{name:"zs", age:12, Book:Book{bookName:"语文",price:45.25}}
fmt.Println(s2.name) // zs
fmt.Println(s2.age) // 12
/*
Student结构体将Book结构体作为一个匿名字段,那么Book结构体中的字段对于Studen来将,就是提升字段
则在Student对象可以直接访问Book中的字段
*/
fmt.Println(s2.Book.bookName) // 语文
fmt.Println(s2.Book.price) // 45.25
// 简写(匿名字段结构体-->字段提升)
fmt.Println(s2.bookName) // 语文
fmt.Println(s2.price) // 45.25
}
结构体匿名字段:
package main
import "fmt"
type Person struct {
string // 匿名字段,匿名字段不能重复,否则报错
int
}
func main() {
s2 := Person{"aa", 12}
// 匿名字段获取数据,将数据类型作为字段名
fmt.Println(s2.string) // aa
fmt.Println(s2.int) // 12
}
结构体嵌套:
因为结构体是值类型,为避免重复开辟内存空间,使用结构体嵌套时,尽量使用结构体指针
package main
import "fmt"
type Book struct {
name string
price float64
}
type Student1 struct {
name string
age int
book Book // 值传递,修改当前结构体数据,不影响原Book结构体数据
}
type Student2 struct {
name string
age int
book *Book // 指针传递,地址引用,修改结构体数据,则原Book结构体数据改变
}
func main() {
book := Book{name:"语文", price:32.4}
s1 := Student{name:"zhangsan", age:12,book=book}
s2 := Student{name:"zhangsan", age:12,book=&book} // 指针,节约内存,按应用场景而定怎么使用
}
指针与结构体应用:
package main
import (
"fmt"
)
type Persion struct {
Name string
Age int
}
func main() {
vv := make([]string, 0)
// kvs := make([]*Persion, 0)
// p := &Persion{Name: "zhangs", Age: 4}
// fmt.Println("p:>>>", p)
// kvs = append(kvs, p)
// p2 := &Persion{Name: "lisi", Age: 43}
// kvs = append(kvs, p2)
kvss := []*Persion{&Persion{Name: "zhangs", Age: 4}, &Persion{Name: "lisi", Age: 46}}
for k, v := range kvss {
fmt.Printf("%s -> %s\n", k, v)
vv = append(vv, v.Name)
}
fmt.Println("aa:", vv)
}