Golang map集合丶struct结构体

发布时间 2023-09-14 08:25:34作者: 看一百次夜空里的深蓝

一.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 }