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
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM