Part13 Maps

欢迎来到 Golang 教程系列的第13部分

什么是 map?

map 是 Go 的内置类型,它将一个值和key关联起来。值可以使用相应的key检索出来。

如何创建一个 map?

map可以通过将 key 和值的类型传递给 make 函数被创建。make(map[type of key]type of value) 是创建map的一个语法。

personSalary := make(map[string]int)

上面的一行是创建一个名字为 personSalary 的 map 的代码,它有一个 string 类型的 key 和 int 类型的值。

map 的空值是 nil。如果你试图给空map增加条目,将发产生一个运行时 panic。因此 map 必须使用 make 函数初始化。

package main

import (  
    "fmt"
)

func main() {  
    var personSalary map[string]int
    if personSalary == nil {
        fmt.Println("map is nil. Going to make one.")
        personSalary = make(map[string]int)
    }
}

在上面的程序中,personSalary 是空的,所以它将被使用 make 函数初始化。该程序将输出 map is nil. Going to make one.

给 map 增加项目

给一个 map 增加项目的语法和数据一样。下面的程序给 personSalary map 增加一些新的项目。

package main

import (  
    "fmt"
)

func main() {  
    personSalary := make(map[string]int)
    personSalary["steve"] = 12000
    personSalary["jamie"] = 15000
    personSalary["mike"] = 9000
    fmt.Println("personSalary map contents:", personSalary)
}

上面程序的输出 personSalary map contents: map[steve:12000 jamie:15000 mike:9000]

在 map 声明的同时初始化也是可以的。

package main

import (  
    "fmt"
)

func main() {  
    personSalary := map[string]int {
        "steve": 12000,
        "jamie": 15000,
    }
    personSalary["mike"] = 9000
    fmt.Println("personSalary map contents:", personSalary)
}

上面的程序声明 personSalary 在声明它的同时给它增加两个元素。然后另外增加 key 为 mike 的元素。程序输出如下:

personSalary map contents: map[steve:12000 jamie:15000 mike:9000]  

并不是只有字符串才可以作为 key。所有可比较的类型,如 boolean,integer, float, complex, string,…也可以作为key,如果你想了解更多关系可比较类型的知识,可以访问 http://golang.org/ref/spec#Comparison_operators

访问 map 的元素

现在我们已经给 map 增加一些元素,让我们学习如何检索它们。map[key] 是检索 map 的语法。

package main

import (  
    "fmt"
)

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

上面的程序很明显,雇员 jamie 的薪水被检索并打印,程序的输出为 Salary of jamie is 15000.

如果一个元素不存在将会发生什么?map 将会返回该元素类型的空值。以 personSalary map 为示例,如果我们尝试访问一个不存在的元素,int 的空值 0 将被返回。

package main

import (  
    "fmt"
)

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

上面程序的输出为:

Salary of jamie is 15000  
Salary of joe is 0  

上面程序返回 joe 的薪水为0。我们并未得到任何运行时错误表明key joe 不存在 personSalary map 中。

如果我们想要知道一个 key 是否存在于 map 中该做什么?

value, ok := map[key]

上面是找出一个特定的 key 是否存在于 map 中的语法。如果 ok 是 true,则该 key 存在,它的值存在于变量 value 中。否则 key 不存在。

package main

import (  
    "fmt"
)

func main() {  
    personSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,
    }
    personSalary["mike"] = 9000
    newEmp := "joe"
    value, ok := personSalary[newEmp]
    if ok == true {
        fmt.Println("Salary of", newEmp, "is", value)
    } else {
        fmt.Println(newEmp,"not found")
    }

}

在上面的程序中,第5行。因为 joe 不存在,所以 ok 是 false,因此程序的输出是:

joe not found

for 循环的 range 被用来迭代 map 的所有的元素

package main

import (  
    "fmt"
)

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

}

上面程序的输出:

All items of a map  
personSalary[mike] = 9000  
personSalary[steve] = 12000  
personSalary[jamie] = 15000 

一个重要的事实是当使用 for range 从一个 map中检索值的时候,并不保证每一次执行程序的顺序是一致的。

删除项目

delete(map,key) 是从 map 中删除 key 的语法。delete 函数并不会返回任何值。

package main

import (  
    "fmt"
)

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

}

上面程序删除key “steve” 并输出

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

map 的长度

map 的长度可以使用 len 函数确定。

package main

import (  
    "fmt"
)

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

}

上面程序中 len(personSalary) 确定了map的长度。上面程序的输出是 length is 3

Maps是引用类型

和 slice一样,maps 是引用类型,当一个map被指定给一个新的变量,它们都指向同一个内部数据类型。因此修改一个的内容会影响另外一个。

package main

import (  
    "fmt"
)

func main() {  
    personSalary := map[string]int{
        "steve": 12000,
        "jamie": 15000,
    }
    personSalary["mike"] = 9000
    fmt.Println("Original person salary", personSalary)
    newPersonSalary := personSalary
    newPersonSalary["mike"] = 18000
    fmt.Println("Person salary changed", personSalary)

}

在上面程序的第14行, personSalary 被赋值给 newPersonSalary ,在下面的一行,在map newPersonSalary中,mike 的薪水修改到 18000,Mike的薪水在 personSalary中现在也是 18000。程序输出如下:

Original person salary map[steve:12000 jamie:15000 mike:9000]  
Person salary changed map[steve:12000 jamie:15000 mike:18000] 

当 map 作为参数传递给函数也一样,当在函数内对 map 做任何的修改,它对于调用者是可见的。

Maps 比较

Map 不可以使用 == 操作符做比较,== 仅可以被用来检验 map 是否为 nil.

package main

func main() {  
    map1 := map[string]int{
        "one": 1,
        "two": 2,
    }

    map2 := map1

    if map1 == map2 {
    }
}

上面的程序将抛出汇编错误 ** invalid operation:map1 == map2(map can only be compared to nil)**

比较两个map是否相等的一种方式是一个一个的检验每一个独立的元素。我鼓励你为些写一个函数并使它工作。

我已经将我们所讨论的所有概念编辑成一个程序。你可以从github上下载

这些是 maps ,感谢阅读

下面的教程是 - Strings

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值