Go 学习笔记 08 | 结构体详解
2020-12-01 本文已影响0人
Wonz
一、结构体
实例化结构体
第一种实例化结构体: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()
}
输出:
小黑 在运动
小黑 在汪汪