Структура 3,11 Go Struct
Golang поддержка ООП объектно-ориентированное программирование.
Перейти структуры struct
как питон class
.
Перейти на структура достижения возможности объектно - ориентированного программирования, только сочетание composition
этой функции.
2. Концепция структуры
1) Свойства класса операции извлечения новый тип данных является структурой.
2) для создания нескольких экземпляров структур.
3) может быть структура Стьюдента, это может быть животное, структура Person.
3. Особенности структуры
1) структура используется для определения сложных структур данных
2) структура может включать в себя множество полей
3) Метод структуры может быть определен (примечание не функционирует, является метод golang)
4) тип значения структуры может быть
5) Тип структуры может быть вложенными
6) не идет класс, только типа структуры
7) структура определены типы не могут быть перенесены на другие виды сильные
8) могут быть добавлены к каждому полю структуры тега, этот тег может быть получен механизм отражения, например, сцена JSon сериализации и десериализации.
4. Структура определяется
package main import "fmt" type Person struct { Name string Age int } func main() { //声明方式 p1 := Person{"小黑", 18} //有序赋值,并且必须包含所有字段,否则报错 p2 := Person{Age: 18} //关键词赋值,未赋值字段有空值 fmt.Println(p1) fmt.Println(p2) }
Упражнение структура
package main import "fmt" //声明结构体名称Stu type Stu struct { Name string //结构体字段 Age int //如未赋值有默认空值 Address string Score int } //结构体可以定义复杂的类型 type Person struct { Name string Age int Score [5]float64 //容量为5的数组 prt *int //指针类型 slice []int //int类型切片 map1 map[string]string //map类型字段 //slice和map默认值是nil,必须make初始化才可使用 } //结构体是值类型,不同结构体实例之间互不影响 type Monster struct { Name string Age int } func main() { //声明结构体类型变量 var stu1 Stu //结构体可以通过 . 的方式赋值,声明赋值方式一 stu1.Name = "小黑" stu1.Age = 18 stu1.Address = "沙河" stu1.Score = 100 fmt.Printf("stu1的名字=%v 年纪=%v 住址=%v 分数=%v\n", stu1.Name, stu1.Age, stu1.Address, stu1.Score) //声明赋值方式二 monster1 := Monster{"红孩儿", 18} monster2 := Monster{"女妖怪", 999} //两个结构体实例,内存地址不一样,确保独立 fmt.Printf("monster1地址:%p\n", &monster1) fmt.Printf("monster2地址:%p\n", &monster2) //声明方式三 //用来分配内存,主要用来分配值类型,比如int、struct。返回指向类型的 指针 //此时m1是一个指针 var m1 *Monster = new(Monster) //给m1赋值 (*m1).Name = "孙悟空" //编译器自动识别 同于 m1.Name="孙悟空" (*m1).Age = 9999 //同上 fmt.Println(*m1) //此时m1是指针变量,加上*取值 //声明方式四 m2 := &Monster{ "猪八戒", 888, } fmt.Println(*m2) //第三、第四种返回结构体指针,go编译器自动识别,简化程序员心智负担,建议用1、2方法 }
4.1.1. Структура Anonymous
Без названия структуры
package main import "fmt" func main() { //匿名函数 func() { fmt.Println("我是匿名函数") }() //匿名结构体 p1 := struct { name string age int }{ name: "张三", age: 18, } fmt.Println(p1) }
4.1.2. AnonymousField
package main import "fmt" func main() { type student struct { string //匿名字段,类型当做字段名 int } s1 := student{ "吴亦凡", 18, } fmt.Println(s1.string, s1.int) }
4.1.3. Структура вложенности
Объектно-ориентированный: отношения агрегации
Класс как свойство другого класса
package main import "fmt" type Book struct { bookName string price float64 author string } type Person struct { name string age int book Book //继承Book结构体的字段 ,模拟聚合关系 } func main() { //先定义好的book对象 b1 := Book{"如何找到女朋友", 999.999, "alex金角大王"} p1 := Person{"武沛奇", 26, b1} //b1就是Book结构体类型,武沛奇买了一本书 fmt.Printf("姓名:%s,年纪:%d,书名:%s,价格:%.2f,书的作者:%s\n", p1.name, p1.age, p1.book.bookName, p1.book.price, p1.book.author) //声明初始化book对象,一行搞定 p2 := Person{"萧峰", 25, Book{"如何找到男朋友", 3.58, "超哥著作"}} fmt.Printf("姓名:%s,年纪:%d,书名:%s,价格:%.2f,书的作者:%s\n", p2.name, p2.age, p2.book.bookName, p2.book.price, p2.book.author) }
结构体嵌套练习
Студенты и стеллаж,
package main import "fmt" type Book struct { bookName string price float64 } type Student struct { name string age int books []*Book } func main() { b1 := Book{"霸道总裁爱上我", 120.22} b2 := Book{"斗破苍穹", 12.5} b3 := Book{"我和师姐的故事", 15.5} //定义书架,默认没有书,可以容纳10本书 //用Book就是值拷贝,*Book就是放入书的内存地址 bookSlice := make([]*Book, 0, 10) //注意需要传入地址 bookSlice = append(bookSlice, &b1, &b2, &b3) //创建一个学生 s1 := Student{"小猪沛奇", 3, bookSlice} fmt.Printf("姓名:%s,年纪:%d\n", s1.name, s1.age) //查看书架上书的信息 for i := 0; i < len(s1.books); i++ { book := s1.books[i] fmt.Printf("\t第%d本书,书名:%s,书价格:%.2f\n", i+1, (*book).bookName, book.price) } //创建图书方式二 //初始化创建时候,必须对切片分配内存 s2 := Student{"特斯拉车主alex", 46, make([]*Book, 0, 10)} //放入书架的书,放入书的内存地址 s2.books = append(s2.books, &Book{"斗罗大陆", 55.3}, &Book{"python入门到放弃", 1.28}, &Book{"王思聪与三个网红的一天", 999999.99}) fmt.Printf("学生名:%s,学习年龄:%d\n", s2.name, s2.age) //输入所有s2学生看的书 for k, v := range s2.books { fmt.Printf("\t第%d本书,书名:%s,价格:%.2f\n", k+1, v.bookName, v.price) } }
4.1.4 Объектно-ориентированный: наследование
Класс как подкласс другого класса: подкласс родительского
Наследование: второй объектно-ориентированные функции, описывают отношения между двумя классами для
Подкласс, производный класс, подкласс наследует родительский класс (супер класс, базовый класс, суперкласс)
Подклассы могут получить доступ к существующим свойствам и методы родительского класса непосредственно
Подкласс может добавить свои собственные свойства и методы
Подкласс метода существующего может также переопределить родительский класс
通过匿名字段的方式,进行嵌套,实现继承关系
package main import "fmt" //1.定义父类 type Person struct { name string age int } //2定义子类,匿名字段,Person即是 type Son struct { Person //模拟继承结构,继承父类的name,age属性 school string //子类的新增属性 } func main() { //父类 p1 := Person{"李靖", 999} fmt.Println(p1.name, p1.age) //子类赋值方式一,子类直接访问父类属性 var s2 Son s2.name = "娜扎" s2.age = 666 s2.school = "神仙学校" fmt.Println(s2, s2.name, s2.age, s2.school) //创建方式二,简写方式 s3 := Son{Person{"木吒", 667}, "神仙学校"} fmt.Println(s3, s3.name, s3.age, s3.school) //创建方式三,基于key-value写 s4 := Son{Person: Person{name: "金吒", age: 668}, school: "神仙学校"} fmt.Println(s4, s4.name, s4.age, s4.school) }
4.1.5 Детали структуры
- Структура поля является непрерывной в памяти
package main import "fmt" type Test struct { A int32 B int32 C int32 D int32 } func main() { var t Test fmt.Printf("a addr:%p\n", &t.A) fmt.Printf("b addr:%p\n", &t.B) fmt.Printf("c addr:%p\n", &t.C) fmt.Printf("d addr:%p\n", &t.D) }
- Структура определяется пользователем, может быть отлито, но оно должно быть точно таким же полем, числа, типа
- Переопределение структуру (повторного типа), тот же самый эффект на структуру
别名
- Каждое поле структуры, тег может быть записан, вкладка может быть получена путем отражения сериализации, десериализации
package main import ( "encoding/json" "fmt" ) type User struct { UserName string `json:"姓名"` //反引号括起来的就是struct tag Sex string `json:"性别"` Score float32 `json:"成绩"` Age int32 `json:"年纪"` } func main() { user := &User{ UserName: "user01", Sex: "男", Score: 99.2, Age: 18, } //将user变量序列化为json格式字符串 data, _ := json.Marshal(user) fmt.Printf("json str:%s\n", string(data)) }
Структура распределения памяти 4.2
Посмотрите на код
package main import "fmt" type Person struct { Name string Age int } func main() { //p1有自己的结构体内存地址, var p1 Person p1.Age = 10 p1.Name = "王大锤" //定义P2 指针类型,指向p1的内存地址 var p2 *Person = &p1 //两种形式一样,go编译器自动识别 fmt.Println((*p2).Age) fmt.Println(p2.Age) //修改p2的结构体值,也就是修改了p1的结构体值 p2.Name = "葫芦娃" fmt.Printf("输出结果 p2.Name=%v p1.Name=%v\n", p2.Name, p1.Name) fmt.Printf("输出结果(*p2).Name=%v p1.Name=%v\n", (*p2).Name, p1.Name) //查看p1和p2的内存地址 fmt.Printf("p1内存地址%p\n", &p1) //p2是指针变量,自己也有一块内存地址,p2的值指向 fmt.Printf("p2内存地址%p p2的值是%v\n", &p2, p2) }