Toggle navigation
主页
English
K8S
Golang
Guitar
About Me
归档
标签
Welcome to Sanger's Blog!
结构体
go
2024-01-10 17:54:46
20
0
0
sanger
go
# 结构体 ## 结构体创建、访问与修改 定义结构体 ```Go type user struct { id int score float32 enrollment time.Time name, addr string //多个字段类型相同时可以简写到一行里 } ``` 声明和初始化结构体 ```Go var u user //声明,会用相应类型的默认值初始化struct里的每一个字段 u = user{} //用相应类型的默认值初始化struct里的每一个字段 u = user{id: 3, name: "zcy"} //赋值初始化 u = user{4, 100.0, time.Now(), "zcy", "beijing"} //赋值初始化,可以不写字段名,但需要跟结构体定义里的字段顺序一致 ``` 访问与修改结构体 ```Go u.enrollment = time.Now() //给结构体的成员变量赋值 fmt.Printf("id=%d, enrollment=%v, name=%s\n", u.id, u.enrollment, u.name)//访问结构体的成员变量 ``` 成员方法 ```Go //可以把user理解为hello函数的参数,即hello(u user, man string) func (u user) hello(man string) { fmt.Println("hi " + man + ", my name is " + u.name) } //函数里不需要访问user的成员,可以传匿名,甚至_也不传 func (_ user) think(man string) { fmt.Println("hi " + man + ", do you know my name?") } ``` 为自定义类型添加方法 ```Go type UserMap map[int]User //自定义类型 //可以给自定义类型添加任意方法 func (um UserMap) GetUser(id int) User { return um[id] } ``` 结构体的可见性: - go语言关于可见的统一规则:大写字母开头跨package也可以访问;否则只能本package内部访问。 - 结构体名称以大写开头时,package外部可见,在此前提下,结构体中以大写开头在成员变量或成员方法在package外部也可见。 匿名结构体 ```Go var stu struct { //声明stu是一个结构体,但这个结构体是匿名的 Name string Addr string } stu.Name = "zcy" stu.Addr = "bj" ``` 匿名结构体通常用于只使用一次的情况。 结构体中含有匿名成员 ```Go type Student struct { Id int string //匿名字段 float32 //直接使用数据类型作为字段名,所以匿名字段中不能出现重复的数据类型 } var stu = Student{Id: 1, string: "zcy", float32: 79.5} fmt.Printf("anonymous_member string member=%s float member=%f\n", stu.string, stu.float32) //直接使用数据类型访问匿名成员 ``` ## 结构体指针 创建结构体指针 ```Go var u User user := &u //通过取址符&得到指针 user = &User{ //直接创建结构体指针 Id: 3, Name: "zcy", addr: "beijing", } user = new(User) //通过new()函数实体化一个结构体,并返回其指针 ``` 构造函数 ```Go //构造函数。返回指针是为了避免值拷贝 func NewUser(id int, name string) *User { return &User{ Id: id, Name: name, addr: "China", Score: 59, } } ``` 方法接收指针 ```Go //user传的是值,即传的是整个结构体的拷贝。在函数里修改结构体不会影响原来的结构体 func hello(u user, man string) { u.name = "杰克" fmt.Println("hi " + man + ", my name is " + u.name) } //传的是user指针,在函数里修改user的成员会影响原来的结构体 func hello2(u *user, man string) { u.name = "杰克" fmt.Println("hi " + man + ", my name is " + u.name) } //把user理解为hello()的参数,即hello(u user, man string) func (u user) hello(man string) { u.name = "杰克" fmt.Println("hi " + man + ", my name is " + u.name) } //可以理解为hello2(u *user, man string) func (u *user) hello2(man string) { u.name = "杰克" fmt.Println("hi " + man + ", my name is " + u.name) } ``` ## 结构体嵌套 ```Go type user struct { name string sex byte } type paper struct { name string auther user //结构体嵌套 } p := new(paper) p.name = "论文标题" p.auther.name = "作者姓名" p.auther.sex = 0 type vedio struct { length int name string user//匿名字段,可用数据类型当字段名 } ``` 结构体嵌套时字段名冲突的问题 ```Go v := new(vedio) v.length = 13 v.name = "视频名称" v.user.sex = 0 //通过字段名逐级访问 v.sex = 0 //对于匿名字段也可以跳过中间字段名,直接访问内部的字段名 v.user.name = "作者姓名" //由于内部、外部结构体都有name这个字段,名字冲突了,所以需要指定中间字段名 ``` ## 深拷贝与浅拷贝 ```Go type User struct { Name string } type Vedio struct { Length int Author User } ``` Go语言里的赋值都会发生值拷贝。  ```Go type User struct { Name string } type Vedio struct { Length int Author *User } ```  - 深拷贝,拷贝的是值,比如Vedio.Length。 - 浅拷贝,拷贝的是指针,比如Vedio.Author。 - 深拷贝开辟了新的内存空间,修改操作不影响原先的内存。 - 浅拷贝指向的还是原来的内存空间,修改操作直接作用在原内存空间上。 传slice,对sclice的3个字段进行了拷贝,拷贝的是底层数组的指针,所以修改底层数组的元素会反应到原数组上。 ```Go users := []User{{Name: "康熙"}} func update_users(users []User) { users[0].Name = "光绪" } ```
上一篇:
初识Go语言
下一篇:
函数
0
赞
20 人读过
新浪微博
微信
更多分享
腾讯微博
QQ空间
人人网
文档导航