Bootstrap

【Golang】六、基础篇 -- map和结构体

一、map 引用类型

map是引用类型

1、定义和初始化

  1. make定义
    // 方式1
    var mapT1 map[string]string
    mapT1 = make(map[string]string, 10)
    // 方式2
    var mapT3 = make(map[string]string)
    // 方式3
    mapT4 := make(map[string]string)
    
    // 赋值
    mapT4["number1"] = "11111"
    mapT4["number2"] = "22222"
    
    // 输出 => map[number1:11111 number2:22222]
    
  2. 普通定义
    var mapT2 = map[int]int{}
    mapT2 := map[int]int{}
    
    // 赋值
    mapT2 := map[int]int{
    	1:1,
    	2:2,
    }
    
    // 输出 => map[1:1 2:2]
    

2、map的嵌套结构

  1. map[int]map[string]string
    type mapSS map[int]map[string]string
    func Anli() {
    	// 方式1
    	students := make(map[int]map[string]string)
    	students[1] = map[string]string{
    		"name": "张三",
    		"sex": "男",
    	}
    	students[2] = map[string]string{
    		"name": "张四",
    		"sex": "男",
    	}
    	students[3] = map[string]string{
    		"name": "张五",
    		"sex": "女",
    	}
    	// fmt.Println(students)
    	// 输出 =》map[1:map[name:张三 sex:男] 2:map[name:张四 sex:男] 3:map[name:张五 sex:女]]
    
    	// 方式2
    	stus := mapSS{
    		1:{
    			"name": "王武",
    			"age": "20",
    		},
    		2:{
    			"name": "王六",
    			"age": "24",
    		},
    		3:{
    			"name": "王七",
    			"age": "30",
    		},
    	}
    	fmt.Println(stus)
    	a, b := stus[1]["name"]
    	fmt.Println(a, reflect.TypeOf(b))
    	// 输出 =》 map[1:map[age:20 name:王武] 2:map[age:24 name:王六] 3:map[age:30 name:王七]]
    }
    
  2. 带入实例理解下
    (1)商品列表:map[int]map[string]string:(一对一)
    	[
    		商品id:{名称:‘’, 描述:‘’},
    		商品id:{名称:‘’, 描述:‘’},
    		........
    	]
    
    (2)商品评价:map[int][]map[string][string] :(一对多)
    	[
    		商品id:[
    			{用户id:1, 评价:‘’},
    			{用户id:2, 评价:‘’},
    			.......
    		],
    		商品id:[
    			{用户id:1, 评价:‘’},
    			{用户id:2, 评价:‘’},
    			.......
    		],
    		........
    	]
    

2、map切片

make([]map[int]int, 2, 4)

func SliceMap() {
	a := make([]map[int]int, 2, 4)
	// 赋值方式1
	a[0] = make(map[int]int)
	a[0][1] = 1
	// 赋值方式2
	a[1] = map[int]int{0:0, 1:1}
	// 切片追加
	a = append(a, map[int]int{2:2})
}

3、map遍历和排序

  1. 遍历
    mapm := map[int]string{
    	11: "测试11",
    	22: "测试22",
    }
    for key, item := range mapm {
    	fmt.Println(key, item)
    }
    
  2. 排序
    golang中map是无序的,没有对map排序的方法。实现思路:先将key放到切片中,对切片排序,遍历切片取出value
func SortMap() {
	mapm := map[int]int{
		10: 1,
		4: 2,
		3: 3,
		13: 3,
		33: 3,

	}
	// 存放map的key的切片
	sliceMap := []int{}
	// map遍历
	for key, _ := range mapm {
		// append key到切片
		sliceMap = append(sliceMap, key)
	}
	// 对切片排序
	sort.Ints(sliceMap)
	// 按照切片顺序遍历
	for _, item  := range sliceMap {
		fmt.Print(mapm[item], "\t")
	}
}

4、map和结构体

// 定义结构体
type stu struct {
	id int
	name string
	age int
}
func StructMap() {
	// map的value指定为结构体类型
	a := map[int]stu{}
	stu1 := stu{
		id: 1,
		name: "张三",
		age: 20,
	}
	stu2 := stu{
		id: 2,
		name: "张三",
		age: 21,
	}
	a[0] = stu1
	a[1] = stu2
	fmt.Println(a)
	fmt.Println(a[0].name)

	a1 := []stu{}
	a1 = append(a1, stu1)
	fmt.Println(a1)
}

5、map增删改查

  1. 增和改
    如果key存在就是跟新,如果不存在就是插入

  2. delete(map[type]type, key)

  3. 方式1:
    // 参数一:key=1 对应的值
    // 参数二:是否存在, 有返回true, 没有返回false
    stu, isOrNo := stus[1]
    
    方式2:
    引用类型没有初始化,引用为nil(空)。值类型,初始化不为nil
    stu := stus[1]
    if stu == nil {
    	// 不存在
    } else {
    	// 存在
    }
    

6、map判断是否存在key

	// 存在 ok:true
	// 不存在反之
	_, ok := map1[1]

二、结构体 值类型

可以理解为一个自定义的数据类型,就是一个结构体(等同于自定义int、string、float等数据类型);创建、引用对象和值类型的基本数据类型一致。

1、定义

type Cat struct {
	Name string
	Age int
	Color string
	Teacher *string
}
func DY() {
	// 方式1
	var cat Cat
	fmt.Println(cat) // 输出 =》{ 0  <nil>}

	// 方式2
	cat2 := Cat{}
	fmt.Println(cat2) // 输出 =》{ 0  <nil>}

	// 方式3 
	// new一个指针,引用类型
	cat3 := new(Cat) //等价 (var cat3 *Cat = new(Cat))
	(*cat3).Name = "aaa"
	cat3.Name = "bbb" // 两种写法都可以,底层转化为=》(*cat3).Name = "bbb"
	fmt.Println(*cat3) // 输出 =》{bbb 0  <nil>}

	// 方式4
	cat4 := &Cat{}
	(*cat4).Name = "111"
	fmt.Println(*cat4) // =》{111 0  <nil>}
}

2、结构体切片

str := ""
cat1 := Cat{"小花", 10, "红色", &str}
cat2 := Cat{"小白", 1, "白色", &str}
sliceCat := []Cat{cat1, cat2}

3、结构体指针

func setCat(cat *Cat) {
	cat.Name = "小小"
	fmt.Println(cat.Name)
}
func main(){
	cat := new(Cat)
	(*cat).Name = "大大"
	// 此处参数是指针,所以是引用传递,会修改当前对象
	setCat(cat)
	fmt.Println(cat)
	// 输出 =》
	// { "小小" }
	// { "小小" }
}

4、结构体序列化

type Cat struct {
	// `json:"name"` 指定序列化后的 Name =》name
	Name string `json:"name"`
	Age int
	Color string
}

func JsonM() {
	str := ""
	cat1 := Cat{"小花", 10, "红色"}
	// json序列化
	catt, err := json.Marshal(cat1)
	// 转化为strings输出,否则为字节码
	fmt.Println(string(catt), err)
	// 输出 =》{"name":"小花","Age":10,"Color":"红色"} <nil>
}

func main(){
	other.JsonM()
}

5、结构体内存结构

结构体每个值的内存地址是连续的,但是指针类型存储的值的地址不是连续
在这里插入图片描述

;