Golang map集合丶struct结构体丶继承

一.map集合

 1 // map键值对集合
 2 func testMap() {
 3     // Map的定义: var 变量名 map[keytType]valueType
 4     // 细节:
 5     // 1.key唯一
 6     // 2.map是引用
 7     // 3.直接遍历map是无序的
 8     // 4.map会自动扩容,make中设置的长度并没有对map任何限制
 9     var m1 = make(map[string]int32, 2)
10     var m2 = map[string]string{
11         "key1": "test1",
12         "key2": "test2",
13         "key3": "test3",
14     }
15     m2["key4"] = "test4"
16     delete(m2, "key2") // 删除操作.如果要删除所有,需要循环删除,或者重新定义后让回收机制回收
17     fmt.Println("m1=", m1)
18     fmt.Println("m2=", m2)
19 
20     // 查找
21     val, b := m2["key4"]
22     fmt.Println("=", val, "  ", b) // = test4    true
23     fmt.Println("=", m2["key4"])   // = test4
24 
25     fmt.Println("================================")
26     // 遍历 第一次
27     for key, val := range m2 {
28         fmt.Println("key=", key, " val=", val)
29     }
30     m2["key5"] = "test5"
31     fmt.Println("===========可以看到map遍历的顺序并不是每次都一样,特别是在新加了元素之后=====================")
32     // 遍历 第二次
33     for key, val := range m2 {
34         fmt.Println("key=", key, " val=", val)
35     }
36     fmt.Println("================================")
37     fmt.Println("===========如果要按固定排序输出的话只能通过keys数组切片去实现顺序输出=====================")
38     var mapIndexs = make([]string, len(m2))
39     temIndex := 0
40     for k, _ := range m2 {
41         mapIndexs[temIndex] = k
42         temIndex++
43     }
44     sort.Strings(mapIndexs)
45     for _, k := range mapIndexs {
46         fmt.Println(m2[k])
47     }
48     fmt.Println("================================")
49     // 集合切片
50     var m3 = make([]map[string]string, 2)
51     m3[0] = map[string]string{
52         "name": "张三",
53         "age":  "20",
54     }
55     m3[1] = map[string]string{
56         "name": "李四",
57         "age":  "19",
58     }
59     w5 := map[string]string{
60         "name": "王五",
61         "age":  "21",
62     }
63     m3 = append(m3, w5)
64     fmt.Printf("%v &m3[0]=%x &m3[1]=%x \n", m3, &(m3[0]), &(m3[1]))
65 
66 }

二.struct结构体

 1 type Person1 struct {
 2     Name string
 3     Age  int16 // 小写开头带表只能本包可用
 4 }
 5 
 6 func (self *Person1) PrintInfo() (result bool) {
 7     self.Name = "张三丰"
 8     fmt.Println("姓名:", self.Name, "\t年龄:", self.Age)
 9     result = true
10     return
11 }
12 
13 // 定义struct方法并不会影响内存分配
14 func (self Person1) PrintInfo1() {
15     self.Name = "张三丰" // 这里并不会修改调用对象
16     fmt.Println("姓名:", self.Name, "\t年龄:", self.Age)
17 }
18 
19 // 给结构体实现String()   那进行强制str转换的时候就是调用这个
20 func (self *Person1) String() string {
21     return fmt.Sprintln("姓名:", self.Name, "\t年龄:", self.Age)
22 }
23 
24 func testStruct() {
25     fmt.Println("=======================struct定义丶访问============================")
26     type Person struct {
27         Name string
28         age  int16 // 本包可用
29     }
30     var p1 Person = Person{Name: "Tom", age: 19}
31     var p2 *Person = new(Person)
32     var p3 *Person = &Person{Name: "Lisa", age: 22}
33     p4 := p1
34     p4.Name = "Jerry11"
35     p1.age = 19
36     p2.age = 99 // 因p2是指针,编译器会将"p2.age = 99" 同等 "(*p2).age = 99"
37     fmt.Println("struct 是值类型,并非引用:", p1, p2, p3, p4)
38     fmt.Println("占用内存大小:", unsafe.Sizeof(p1.Name))
39     fmt.Println("占用内存大小:", unsafe.Sizeof(p4.Name))
40     fmt.Println()
41     fmt.Println("============================使用细节===================================")
42     // 1.属性名小写,只能在本包中访问
43     // 2.指针:  "*p2.age = 99" 中的"."优先级高于"*" 所以必须"(*p2.age) = 99"  或者不用"*"
44     // 3.结构体中的属性,内存分配是连续的.
45     // 4.不同struct类型变量如果要强制转换的话,必须声明定义的属性字段类型顺序相同
46     // 5.struct中提供tag来协助序列与反序列转化(struct转json或反过来[反射])
47     type Monster struct {
48         Name  string `json:"name"`
49         Age   int16  `json:"age"`
50         Skill string `json:"skill"`
51     }
52     m1 := Monster{"关羽", 101, "大宝剑"}
53     jsonstr, _ := json.Marshal(m1) // 如果将属性首字母改称小写,在这里json包中就访问不到了.所以就需要用到tag了
54     fmt.Println(string(jsonstr))
55     fmt.Println()
56     fmt.Println("============================struct 方法 ===================================")
57     // 定义语法:func (self Person1) PrintInfo() (result bool) {
58     // 注意细节:
59     // 1.给struct定义方法并不会影响struct内存分配
60     // 2.首参为指针类型的时候才是self,不然self只是值传递
61     // 3.语法中的Person1类型,并不一定要是struct,可以是任何自定义类型
62     // 4.给结构体实现String()方法   那进行Println输出的时候就是调用这个
63     p5 := Person1{"Carry", 30}
64     fmt.Println(unsafe.Sizeof(p5))
65     p5.PrintInfo() // 同等:(&p5).PrintInfo()    注意:不管你这里从"(&p5)."还是"p5."来调用,编译器都会去设配结构体"PrintInfo()"方法的定义去设配
66     fmt.Println("Println:", &p5)
67 
68     fmt.Println()
69     fmt.Println("============================struct 工厂模式 ===================================")
70     // 工厂模式:定义的结构体为私有的,外部想要获得,只能通过工厂统一创建初始化(具体代码看student包)
71     stu1 := student.StudentFactory("三年级(2)班", "陈是凯", 13, 85)
72     fmt.Println(stu1)
73     stu2 := student.HighStudentFactory("三年级(1)班", "吴开军", 26, 75,
74         "打篮球", 9, 2002, 1, 15,
75         178)
76     fmt.Println(stu2)
77 
78 }

三.struct继承

 1 package student
 2 
 3 import (
 4     "fmt"
 5     "strconv"
 6 )
 7 
 8 // 工厂模式:struct结构体为私有的,通过工厂方法返回结构体变量
 9 func HighStudentFactory(classID string, name string, age int8, score int16,
10     hobby string, hobbyScore int16,
11     byear uint16, bmonth uint16, bday uint16,
12     heightCM uint16) (result *HighStudent) {
13 
14     result = &HighStudent{
15         Person:   Person{ClassID: classID, Name: name, Age: age, score: score},
16         Hobby:    Hobby{Name: hobby, score: hobbyScore},
17         Birthday: Birthday{Year: byear, Month: bmonth, Day: bday},
18         HeightCM: 172,
19     }
20 
21     return
22 }
23 
24 /* student结构体在factory文件中. 这样重新定义类型,原来student的方法并不会跟过来 */
25 type Person student
26 
27 /* 但是这样继承,原来student的方法会跟过来 */
28 type Person1 struct {
29     student
30 }
31 
32 type Hobby struct {
33     Name  string
34     score int16
35 }
36 
37 type Birthday struct {
38     Year  uint16
39     Month uint16
40     Day   uint16
41 }
42 
43 /* 正常项目不要用这种多重继承方式,会严重干扰你的思绪 */
44 type HighStudent struct {
45     Person   // 继承
46     Hobby    // 继承
47     Birthday // 继承
48     HeightCM uint16
49 }
50 
51 func (self *Hobby) String() string {
52     return self.Name + "\t热度:" + strconv.Itoa(int(self.score))
53 }
54 
55 func (self *Birthday) String() string {
56     return fmt.Sprintf("%d年%d月%d日", self.Year, self.Month, self.Day)
57 }
58 
59 func (self *HighStudent) String() string {
60     s1 := student(self.Person).String() // 因为Person和student完全一样所以可以直接强制转换
61     s2 := self.Birthday.String()
62     s3 := self.Hobby.String()
63     return fmt.Sprintf("%v\n生日:%v\n身高:%v\n爱好:%v\n", s1, s2, self.HeightCM, s3)
64 }
65 
66 func TestAddress() {
67     stu1 := Person1{student{"八年级(2)班", "五栋梁", 25, 99}}
68 
69     fmt.Println(stu1.GetScoreRate())
70 }

 

posted @ 2023-09-14 08:19  看一百次夜空里的深蓝  阅读(175)  评论(0编辑  收藏  举报