13、Maps

152 阅读3分钟

本文为译文 Maps

map是go的内置数据结构。

创建一个map的语法如下

make(map[type of key]type of value)  


employeeSalary := make(map[string]int)  

employeeSalary["steve"] = 12000
employeeSalary["jamie"] = 15000
employeeSalary["mike"] = 9000

//Retrieving value for a key from a map
salary := employeeSalary["mike"]

//employeeSalary map contents: map[steve:12000 jamie:15000 mike:9000]  
fmt.Println("employeeSalary map contents:", employeeSalary)



//It is also possible to initialize a map during the declaration itself.
employeeSalary := map[string]int {
        "steve": 12000,
        "jamie": 15000,
    }
employeeSalary["mike"] = 9000

所有的可比较类型都可以做map的key.如 boolean, integer, float, complex, string甚至用户定义的struct也可以做key。如果你不了解什么是可比较类型,可以参考这个文章golang.org/ref/spec#Co…

map的zero value

map的零值是nil,如果你给添加一个元素给nil map的话,那么就会产生一个运行时错误panic: assignment to entry in nil map因此map必须被初始化,在赋值之前。

package main

func main() {  
    var employeeSalary map[string]int
    employeeSalary["steve"] = 12000
}
//panic: assignment to entry in nil map

根据key查value

package main

import (  
    "fmt"
)

func main() {  
    employeeSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,
        "mike": 9000,
    }
    employee := "jamie"
    salary := employeeSalary[employee]
   
    //jamie   15000
    fmt.Println("Salary of", employee, "is", salary) 
    
    //0
    fmt.Println("Salary of joe is", employeeSalary["joe"])
}

如果key对应的value不存在,则会返回改value类型的zero value

检查key是否存在

value, ok := map[key]

如果ok是true则存在。否则不存在

map元素遍历

package main

import (  
    "fmt"
)

func main() {  
    employeeSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,
        "mike":  9000,
    }
    fmt.Println("Contents of the map")
    for key, value := range employeeSalary {
        fmt.Printf("employeeSalary[%s] = %d\n", key, value)
    }
}

package main

import (  
    "fmt"
)

type employee struct {  
    salary  int
    country string
}

func main() {  
    emp1 := employee{
        salary:  12000,
        country: "USA",
    }
    emp2 := employee{
        salary:  14000,
        country: "Canada",
    }
    emp3 := employee{
        salary:  13000,
        country: "India",
    }
    employeeInfo := map[string]employee{
        "Steve": emp1,
        "Jamie": emp2,
        "Mike":  emp3,
    }

    for name, info := range employeeInfo {
        fmt.Printf("Employee: %s Salary:$%d  Country: %s\n", name, info.salary, info.country)
    }

}

注意range出来的key的顺序不是固定的。

key删除

delete(map, key) is the syntax to delete key from a map. The delete function does not return any value.

package main

import (  
    "fmt"
)

func main() {  
    employeeSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,     
        "mike": 9000,
    }
    fmt.Println("map before deletion", employeeSalary)
    delete(employeeSalary, "steve")
    fmt.Println("map after deletion", employeeSalary)
}

map before deletion map[steve:12000 jamie:15000 mike:9000]  
map after deletion map[mike:9000 jamie:15000]

If we try to delete a key that is not present in the map, there will be no runtime error.

map的length

package main

import (  
    "fmt"
)

func main() {  
    employeeSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,
    }
    fmt.Println("length is", len(employeeSalary))
}

map是引用类型

与slice类似,maps是引用类型。当一个map被赋值给另一个变量,那么他们两个指向相同的内部数据结构,因此如果只要一个发生改变,就会影响另一个。

package main

import (  
    "fmt"
)

func main() {  
    employeeSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,     
        "mike": 9000,
    }
    fmt.Println("Original employee salary", employeeSalary)
    modified := employeeSalary
    modified["mike"] = 18000
    fmt.Println("Employee salary changed", employeeSalary)

}

Original employee salary map[jamie:15000 mike:9000 steve:12000]  
Employee salary changed map[jamie:15000 mike:18000 steve:12000]  

map相等比较

map不能用==比较。==只能用来检测map是不是等于nil。一种办法是一个一个比较map上的key。另一种是用反射reflect