golang结构体和map的区别

一、map 引用类型

 

1、定义和初始化

1.1使用make定义map

定义结构体方式1: 先声明map,再make初始化
var m1 map[string]string
//这种定义,必须先使用make初始化后,才可以对map赋值。
//否则抛出异常:panic: assignment to entry in nil map

m1 = make(map[string]string, 10)

定义结构体方式2: 直接初始化,创建map
var m2 = make(map[string]string, 10)

定义结构体方式3:直接初始化,推导出map
m3 := make(map[string]string, 10)

 

 

 

1.2直接赋值的方式定义map:通过直接赋值定义的map,可以直接使用map,不需要再make

定义结构体方式1:
var m4 = map[string]string{}

定义结构体方式2:
m5 := map[string]string{}
m6 := map[string]string{"a": "aaaa"}

 

 

 

// 查找键值是否存在
if v, ok := m1["a"]; ok {
    fmt.Println(v)
} else {
    fmt.Println("Key Not Found")
}

// 遍历map
for k, v := range m1 {
    fmt.Println(k, v)
}

 

2、map的嵌套结构

方式1:
students := make(map[int]map[string]string, 10)
students[1] = map[string]string{
  "姓名": "张三",  
}

students[2] = map[string]string{
  "姓名": "json",  
}


方式2:
type s map[int]map[string]string
ss := s{
    1: {
      "姓名": "张三",  
    },
    2: {
      "姓名": "json",  
    },          
}

 

示列:

1)商品列表:map[int]map[string]string:(一对一)
[
    商品1:{"商品名称": "神舟1号","描述":"好"},
    商品2:{"商品名称": "神舟2号","描述":"好"},
    ...  
]

商品评价:map[int][]map[string][string] :(一对多)
[
    商品1:[
        {"用户id1": "神舟1号","评价":"好"},
        {"用户id2": "神舟2号","评价":"好"}
    ]
    ...  
]        

 

 

3.map切片:make([]map[int]int, 2, 4)

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})

 

4、map遍历和排序
4.1 遍历

mapm := map[int]string{
    11: "测试11",
    22: "测试22",
}
for key, item := range mapm {
    fmt.Println(key, item)
}

 

4.2 排序
golang中map是无序的,没有对map排序的方法。(map相当于py的字典。)

5.map增删改查

  • 增和改:如果key存在就是跟新,如果不存在就是插入
  • 删:delete(map[type]type, key)
    •   方式1:
      value,ok := m[key]

 

    •   方式2
      value := m[key]
      if value == nil {
          fmt.Println(key不存在)  
      }

       

二、结构体 值类型

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

1.定义结构体

type cat struct {
    Name string
    Age int
}

 

2.结构体使用

    // 方式1:
    var c1 Cat
    fmt.Println(c1) //{}

    // 方式2:
    c2 := Cat{}
    fmt.Println(c2) //{}

    // 方式3:
    c3 := new(Cat)
    fmt.Println(c3) // &{},注意new的结果是指针
    // 指针赋值
    (*c3).Name = "黑猫"
    fmt.Println(c3)  // &{黑猫}
    
    // 方式4:
    c4 := &Cat{}  // 使用指针
    (*c4).Name = "黑猫"
    fmt.Println(c3)  // &{黑猫}

 

3.结构体切片

c1 := Cat{"小黑"}
c2 := Cat{"小花"}

//结构体切片
s1 := []Cat{c1, c2}

 


4.结构体指针

结构体只值类型,如果不穿指针,不会修改其内部的值。

func set1 (c Cat) {
    c.Name = "新名字"
    fmt.Println(c.Name) // 新名字
}

func main() {
    cat := Cat{"小花"}
    set1(cat)
    fmt.Println(cat.Name) //还是原来的名字
}

 

 

如果使用结构体指针,将修改其内部值。(变为引用类型)

func set2 (c *Cat) {
    c.Name = "新名字"
    fmt.Println(c.Name) // 新名字
}
func main() {
    cat := Cat{"小花"}
    set2(&cat)
    fmt.Println(cat.Name) // 新名字
}

 

 

5.结构体序列号

import (
    "fmt"
    "encoding/json"
)
type Dog struct {
    Name string `json:"name"`
    Age int    `json:"-"`  // 标记为json:"-",,则不处理这个字段
    Color string   //没有标记json的,原样返回为Color
}

func main() {
    dog := Dog{"小花", 10, "红色"}
    d1, err := json.Marshal(dog)  //返回json对象,且为bytes字节码
    // {"name":"小花","Color":"红色"} <nil>
    fmt.Println(string(d1), err) // bytes转为string
}

 

posted on 2021-11-07 20:29  myworldworld  阅读(1600)  评论(0)    收藏  举报

导航