一、结构体
实例化结构体
第一种实例化结构体:var 变量 结构体
package main import ( "fmt" ) type Person struct { name string age int sex string } func main() { var p1 Person // 实例化 Person 结构体 p1.name = "张三" p1.sex = "男" p1.age = 20 fmt.Printf("值:%v 类型:%T\n", p1, p1) fmt.Printf("值:%#v 类型:%T", p1, p1) }
输出:
值:{张三 20 男} 类型:main.Person 值:main.Person{name:"张三", age:20, sex:"男"} 类型:main.Person
结构体首字母可以大写也可以小写,大写表示这个结构体是公有的,在其他包里面可以使用,小写表示这个结构体是私有的,只有在这个包里面才能使用。
第二种实例化结构体:new 关键词
在 Golang 中支持对结构体指针直接使用.
来访问结构体的成员。p2.name = "张三"
其实在底层是 (*p2).name = "张三"
。
package main import ( "fmt" ) type Person struct { name string age int sex string } func main() { var p2 = new(Person) p2.name = "李四" p2.sex = "男" p2.age = 20 fmt.Printf("值:%v 类型:%T\n", p2, p2) (*p2).name = "王五" fmt.Printf("值:%v 类型:%T\n", p2, p2) }
输出:
值:&{李四 20 男} 类型:*main.Person 值:&{王五 20 男} 类型:*main.Person
第三种实例化结构体:取结构体地址
package main import ( "fmt" ) type Person struct { name string age int sex string } func main() { var p3 = &Person{} p3.name = "赵四" p3.sex = "男" p3.age = 20 fmt.Printf("值:%v 类型:%T\n", p3, p3) }
输出:
值:&{赵四 20 男} 类型:*main.Person
第四种实例化结构体:键值对
package main import ( "fmt" ) type Person struct { name string age int sex string } func main() { var p4 = Person{ name: "哈哈", // 必须加, sex: "男", age: 20, } fmt.Printf("值:%v 类型:%T\n", p4, p4) }
输出:
值:{哈哈 20 男} 类型:main.Person
第五种实例化结构体:键值对
package main import ( "fmt" ) type Person struct { name string age int sex string } func main() { var p5 = &Person{ name: "王二狗", sex: "男", age: 20, } fmt.Printf("值:%v 类型:%T\n", p5, p5) }
输出:
值:&{王二狗 20 男} 类型:*main.Person
第六种实例化结构体:省略 key,但是顺序要一致
package main import ( "fmt" ) type Person struct { name string age int sex string } func main() { var p6 = &Person{ "狗蛋", 20, "男", } fmt.Printf("值:%v 类型:%T\n", p6, p6) }
输出:
值:&{狗蛋 20 男} 类型:*main.Person
二、结构体方法
package main import ( "fmt" ) type Person struct { name string age int sex string } func (p Person) PrintInfo() { fmt.Printf("姓名: %v 年龄: %v\n", p.name, p.age) } func main() { var p = Person{ name: "张三", age: 20, sex: "男", } p.PrintInfo() }
输出:
姓名: 张三 年龄: 20
结构体是值类型。
Golang 中结构体实例是独立的,不会相互影响。
package main import ( "fmt" ) type Person struct { name string age int sex string } func (p Person) PrintInfo() { fmt.Printf("姓名: %v 年龄: %v\n", p.name, p.age) } func (p *Person) SetInfo(name string, age int) { p.name = name p.age = age } func main() { var p1 = Person{ name: "张三", age: 20, sex: "男", } p1.PrintInfo() var p2 = Person{ name: "王五", age: 22, sex: "男", } p1.SetInfo("李四", 34) p1.PrintInfo() p2.PrintInfo() }
输出:
姓名: 张三 年龄: 20 姓名: 李四 年龄: 34 姓名: 王五 年龄: 22
三、结构体嵌套和继承
结构体的匿名字段
结构体允许其成员字段在声明时没有字段名而只有类型,这种没有名字的字段就称为匿名字段。
匿名字段默认采用类型名作为字段名,结构体要求字段名称必须唯一,因此一个结构体中同种类型的匿名字段只能有一个。
package main import ( "fmt" ) type Person struct { string int } func main() { p := Person{ "张三", 20, } fmt.Println(p) }
输出:
{张三 20}
结构体带 map
package main import ( "fmt" ) type Person struct { Name string Age int Hobby []string map1 map[string]string } func main() { var p Person p.Name = "张三" p.Age = 20 p.Hobby = make([]string, 3, 6) p.Hobby[0] = "写代码" p.Hobby[1] = "打篮球" p.Hobby[2] = "睡觉" p.map1 = make(map[string]string) p.map1["address"] = "北京" p.map1["phone"] = "1234567890" fmt.Printf("%#v\n", p) fmt.Printf("%v", p.Hobby) }
输出:
main.Person{Name:"张三", Age:20, Hobby:[]string{"写代码", "打篮球", "睡觉"}, map1:map[string]string{"address":"北京", "phone":"1234567890"}} [写代码 打篮球 睡觉]
结构体嵌套
package main import ( "fmt" ) type User struct { Username string Password string Address Address } type Address struct { Name string Phone string City string } func main() { var u User u.Username = "张三" u.Password = "123456" u.Address.Name = "李四" u.Address.Phone = "1234567890" u.Address.City = "北京" fmt.Printf("%v\n", u) }
输出:
{张三 123456 {李四 1234567890 北京}}
嵌套匿名结构体
package main import ( "fmt" ) type User struct { Username string Password string Address } type Address struct { Name string Phone string City string } func main() { var u User u.Username = "张三" u.Password = "123456" u.Address.Name = "李四" u.Address.Phone = "1234567890" u.Address.City = "北京" fmt.Printf("%#v\n", u) fmt.Printf("%v\n", u) }
输出:
{张三 123456 {李四 1234567890 北京}}
当访问结构体成员时会在结构体中查找该字段,找不到再去匿名结构体中查找。
package main import ( "fmt" ) type User struct { Username string Password string Address } type Address struct { Name string Phone string City string } func main() { var u User u.Username = "张三" u.Password = "123456" u.Address.Name = "李四" u.Address.Phone = "1234567890" u.City = "北京" fmt.Printf("%v\n", u) fmt.Printf("%v\n", u.City) }
输出:
{张三 123456 {李四 1234567890 北京}} 北京
四、结构体继承
package main import ( "fmt" ) // 父结构体 type Animal struct { Name string } func (a Animal) run() { fmt.Printf("%v 在运动\n", a.Name) } // 子结构体 type Dog struct { Age int Animal // 结构体继承 } func (d Dog) wang() { fmt.Printf("%v 在汪汪\n", d.Name) } func main() { var d = Dog{ Age: 20, Animal: Animal{ Name: "小黑", }, } d.run() d.wang() }
输出:
小黑 在运动 小黑 在汪汪