失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Go语言学习笔记-Go语言结构体

Go语言学习笔记-Go语言结构体

时间:2020-08-15 03:58:00

相关推荐

Go语言学习笔记-Go语言结构体

Go语言学习笔记-Go语言结构体

Go语言结构体1. 结构体创建、访问与修改1.1 定义结构体1.2 声明和初始化结构体1.3 访问与修改结构体1.4 成员函数(方法)1.5 为自定义类型添加方法1.6 匿名结构体1.7 结构体中含有匿名成员 2. 结构体指针2.1 创建结构体指针2.2 方法接收指针 3. 结构体嵌套4. 深拷贝与浅拷贝

Go语言结构体

1. 结构体创建、访问与修改

1.1 定义结构体

//定义user结构体type user struct {id intscore float32enrollment time.Timename, addr string //多个字段类型相同时可以简写到一行里}

1.2 声明和初始化结构体

var u user //声明,会用相应类型的默认值初始化struct里的每一个字段u = user{} //用相应类型的默认值初始化struct里的每一个字段u = user{id: 3, name: "xiaoming"} //赋值初始化u = user{4, 100.0, time.Now(), "xiaoming", "beijing"} //赋值初始化,可以不写字段名,但需要跟结构体定义里的字段顺序一致

1.3 访问与修改结构体

u.enrollment = time.Now() //给结构体的成员变量赋值fmt.Printf("id=%d, enrollment=%v, name=%s\n", u.id, u.enrollment, u.name)//访问结构体的成员变量

1.4 成员函数(方法)

//可以把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?")}

1.5 为自定义类型添加方法

type UserMap map[int]User //自定义类型//可以给自定义类型添加任意方法func (um UserMap) GetUser(id int) User {return um[id]}

结构体的可见性:

go语言关于可见的统一规则:大写字母开头跨package也可以访问;否则只能本package内部访问。结构体名称以大写开头时,package外部可见,在此前提下,结构体中以大写开头在成员变量或成员方法在package外部也可见。

1.6 匿名结构体

var stu struct { //声明stu是一个结构体,但这个结构体是匿名的Name stringAddr string}stu.Name = "zcy"stu.Addr = "bj"

匿名结构体通常用于只使用一次的情况。

1.7 结构体中含有匿名成员

type Student struct {Id intstring //匿名字段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) //直接使用数据类型访问匿名成员

2. 结构体指针

2.1 创建结构体指针

var u Useruser := &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,}}

2.2 方法接收指针

//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)}

3. 结构体嵌套

type user struct {name stringsex byte}type paper struct {name stringauther user //结构体嵌套}p := new(paper)p.name = "论文标题"p.auther.name = "作者姓名"p.auther.sex = 0type vedio struct {length intname stringuser//匿名字段,可用数据类型当字段名}

结构体嵌套时字段名冲突的问题

v := new(vedio)v.length = 13v.name = "视频名称"v.user.sex = 0 //通过字段名逐级访问v.sex = 0 //对于匿名字段也可以跳过中间字段名,直接访问内部的字段名v.user.name = "作者姓名" //由于内部、外部结构体都有name这个字段,名字冲突了,所以需要指定中间字段名

4. 深拷贝与浅拷贝

type User struct {Name string}type Vedio struct {Length intAuthor User}

Go语言里的赋值都会发生值拷贝。

type User struct {Name string}type Vedio struct {Length intAuthor *User}

深拷贝,拷贝的是值,比如Vedio.Length。浅拷贝,拷贝的是指针,比如Vedio.Author。深拷贝开辟了新的内存空间,修改操作不影响原先的内存。浅拷贝指向的还是原来的内存空间,修改操作直接作用在原内存空间上。

结构体slice传参

传slice,对sclice的3个字段进行了拷贝,拷贝的是底层数组的指针,所以修改底层数组的元素会反应到原数组上。

users := []User{{Name: "康熙"}}func update_users(users []User) {users[0].Name = "光绪"}

本次课程演示代码

//main.gopackage mainimport struct2 "week03/struct"//type User struct {//Name string//}////func update_users(users []*User) {//users[0].Name = "光绪"//}func main() {//struct2.Init_struct()//struct2.TestSelftype()//b := struct2.Bird{}//b.Walk()struct2.TestStructPoint()//users := []User{{Name: "康熙"}, {Name: "小明"}} //光绪//a := User{Name: "康熙"}//b := User{Name: "小明"}//users := []*User{&a, &b} //发生了拷贝//update_users(users)//fmt.Println(users[0].Name) //光绪//fmt.Println(a.Name) //康熙}//basic.gopackage struct2import "fmt"type student struct {Id intName, address string}func (_ student) Walk() {fmt.Println("runing")}type Bird struct{}func (Bird) Walk() {fmt.Println("fly")}func (a student) sing(man string) {fmt.Println("hello " + man + " " + a.address)}func Init_struct() {var a studentfmt.Printf("%d %s %s\n", a.Id, a.Name, a.address) //0a = student{}fmt.Printf("%d %s %s\n", a.Id, a.Name, a.address) //0a = student{Id: 4}fmt.Printf("%d %s %s\n", a.Id, a.Name, a.address) //4a.Id = 7a.Name = "xiaoming"fmt.Printf("%d %s %s\n", a.Id, a.Name, a.address) //7 xiaoming}type A struct {Id int}var ccc struct {Id intName string}func f() {var sss Afmt.Println(sss.Id)var ddd Afmt.Println(ddd.Id)fmt.Println(ccc.Id)}//sp.gopackage struct2import "fmt"func hello1(u student) {u.Id = 888fmt.Println(u.Id) //888}func hello2(u *student) {u.Id = 888fmt.Println(u.Id) //888}func (u student) hello1() {u.Id = 888fmt.Println(u.Id) //888}func (u *student) hello2() {u.Id = 888fmt.Println(u.Id) //888}func TestStructPoint() {var s student //s.Id=0//hello1(s)s.hello1()fmt.Println(s.Id) //0//hello2(&s)s.hello2()fmt.Println(s.Id) //888}//self_type.gopackage struct2import ("fmt")type AAA intfunc (AAA) Say() {fmt.Println("say")}func (AAA) Hello() {fmt.Println("hello")}func TestSelftype() {var v AAAv = 345fmt.Printf("%d\n", v)v.Say()v.Hello()}// 构造函数func NewStrudent(id int) *student {s := student{}s.Id = ids.address = "BJ"s.Name = "小张"return &s}func testConstruct() {a := NewStrudent(100)fmt.Println(a.address)}//父类type Animal struct {}//子类type Human struct {}// 匿名时候type Vedio struct {Name stringstudent}func TsetNest() {v := Vedio{Name: "tlbb"}v.student = student{Id: 123, Name: "jy", address: "sh"}fmt.Println(v.Name) //tlbbfmt.Println(v.student.Id) //123fmt.Println(v.Id) //Id和address本来是student成员,现在Vedio可以直接访问,即Vedio直接拥有了Id和address,形式上等价于Vedio继承了studentfmt.Println(v.address)//shfmt.Println(v.student.Name) //jy}// 不匿名时候//type Vedio struct {//Name string//s student//}////func TsetNest() {//v := Vedio{Name: "tlbb"}//v.s = student{Id: 123, Name: "jy", address: "sh"}//fmt.Println(v.Name)//tlbb//fmt.Println(v.s.Id)//123//fmt.Println(v.s.Id)//123//fmt.Println(v.s.address) //sh//fmt.Println(v.s.Name) //jy//}

如果觉得《Go语言学习笔记-Go语言结构体》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。