3.11ゴー構造体の構造
サポートOOPオブジェクト指向プログラミングをGolang。
構造の行くstruct
Pythonなどclass
。
OOPの機能の組み合わせのみ達成構造体上に行くcomposition
、この機能を。
2.構造のコンセプト
1)トランザクションのクラスのプロパティは、新しいデータ型を抽出する構造です。
2)構造の複数のインスタンスを作成します。
3)それは動物、人構造であってもよい、学生構造であってもよいです。
3.構造の特徴
1)構造体は、複雑なデータ構造を定義するために使用され
2)構造体は、複数のフィールドを含んでいてもよいです
3)構造体のメソッドを定義することができる(注記しない関数は、golang方法です)
4)構造体の値型であってもよいです
5)構造体のタイプは、ネストすることができます
6)は、クラス、構造体のみのタイプを行きます
7)構造が定義されたタイプが強い他のタイプに転送することができません
8)各フィールド構造体タグに追加することができる、このタグは、シーンJSONシリアライゼーションおよびデシリアライゼーションのように、反射機構を取得してもよいです。
前記構造が定義されています
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。匿名構造
名前のない構造ません
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オブジェクト指向:継承
他のクラスのサブクラスとしてクラス:サブクラスの親
継承:第二のオブジェクト指向の特徴は、のための2つのクラス間の関係を説明します
サブクラスで、派生クラス、サブクラスは親クラス(スーパークラス、基底クラス、スーパークラス)を継承します
サブクラスは、直接親クラスの既存のプロパティとメソッドにアクセスすることができます
サブクラスは、独自のプロパティとメソッドを追加することができます
サブクラスの既存の方法はまた、親クラスをオーバーライドすることができます
通过匿名字段的方式,进行嵌套,实现继承关系
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) }
- 構造は、ユーザによって定義されて鋳造することができるが、それはまったく同じフィールドである必要があり、数、種類
- (RE型)の構造、構造上の同じ効果を再定義
别名
- 各構造体のフィールド、タグを書き込むことができますが、タブをシリアライズ、デシリアライゼーションので反射することによって得ることができます
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) }