安裝本網站至主畫面:

[Go][Golang] 程式設計教學:映射 (Map)

PUBLISHED ON SEP 24, 2017 — PROGRAMMING
Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

    在上一篇文章中,我們介紹了兩個線性的容器:陣列和切片,這兩個容器皆以數字為索引。在本章中,我們會介紹映射 (map),這是另外一種容器;映射儲存鍵/值 (key/value) 對,可以用數種資料型別做為鍵,取得相對應的值。

    註:map 有些教材不翻,也有些教材翻成映射,本文取後者;相同的概念可見於 Python 的字典 (dictionary)、Perl 的雜湊 (hash) 和 PHP 的關連性陣列 (associative array) 等。

    以下實例建立一個以字串為鍵、以字串為值的映射:

    package main
     
    import (
        "log"
    )
     
    func main() {
        // Declare an empty map.
        m := make(map[string]string)
     
        // Insert key/value pairs
        m["Go"] = "Beego"
        m["Python"] = "Django"
        m["Ruby"] = "Rails"
        m["PHP"] = "Laravel"
     
        // Call the value by the key.
        if !(m["Go"] == "Beego") {
            log.Fatal("Wrong value")
        }
     
    }
    

    如果鍵/值對不存在,會依映射的值的型別回傳預設值。在此例中,回傳空字串:

    package main
     
    import (
        "log"
    )
     
    func main() {
        m := make(map[string]string)
     
        m["Go"] = "Beego"
        m["Python"] = "Django"
        m["Ruby"] = "Rails"
        m["PHP"] = "Laravel"
     
        // No such key/value pair.
        if !(m["Java"] == "") {
            log.Fatal("Wrong value")
        }
    }
    

    如果不確定鍵/值對是否存在,可以用以下語法檢查:

    package main
     
    import (
        "log"
    )
     
    func main() {
        m := make(map[string]string)
     
        m["Go"] = "Beego"
        m["Python"] = "Django"
        m["Ruby"] = "Rails"
        m["PHP"] = "Laravel"
     
        v, ok := m["Go"]
        if !ok {
            log.Fatal("It should be true")
        }
     
        if !(v == "Beego") {
            log.Fatal("Wrong value")
        }
     
        _, ok = m["Java"]
        if !(ok == false) {
            log.Fatal("It should be false")
        }
    }
    

    我們也可以用 delete 函式去除鍵/值對:

    package main
     
    import (
        "log"
    )
     
    func main() {
        m := make(map[string]string)
     
        m["Go"] = "Beego"
        m["Python"] = "Django"
        m["Ruby"] = "Rails"
        m["PHP"] = "Laravel"
     
        _, ok := m["PHP"]
        if !ok {
            log.Fatal("It should exist")
        }
     
        // Remove the key/value pair.
        delete(m, "PHP")
     
        _, ok = m["PHP"]
        if !(ok == false) {
            log.Fatal("It should not exist")
        }
    }
    

    映射的鍵/值對是單向的,我們僅能由鍵得到值,但不能由值得到鍵;另外,鍵不能重覆,但值可以。

    類似於陣列和切片,我們也可以用迭代器走訪映射:

    package main
     
    import (
        "fmt"
    )
     
    func main() {
        m := make(map[string]string)
     
        m["Go"] = "Beego"
        m["Python"] = "Django"
        m["Ruby"] = "Rails"
        m["PHP"] = "Laravel"
     
        for k, v := range m {
            fmt.Println(fmt.Sprintf("%s: %s", k, v))
        }
    }
    

    要注意的是,映射是無序的,我們多執行幾次,就會發現每次的順序都不一樣,見下例:

    package main
     
    import (
        "fmt"
    )
     
    func main() {
        m := make(map[string]string)
     
        m["Go"] = "Beego"
        m["Python"] = "Django"
        m["Ruby"] = "Rails"
        m["PHP"] = "Laravel"
     
        for i := 0; i < 10; i++ {
            for k, v := range m {
                fmt.Println(fmt.Sprintf("%s: %s", k, v))
            }
     
            fmt.Println("")
        }
    }
    

    如果想要保持鍵/值對的順序,我們要額外儲存鍵在一個切片中,見下例:

    package main
     
    import "fmt"
     
    func main() {
        // Create an anomynous struct.
        data := struct {
            m     map[string]string
            order []string
        }{
            m:     make(map[string]string),
            order: []string{},
        }
     
        // Insert several key/value pairs.
        data.m["Go"] = "Beego"
        data.order = append(data.order, "Go")
     
        data.m["Python"] = "Django"
        data.order = append(data.order, "Python")
     
        data.m["Ruby"] = "Rails"
        data.order = append(data.order, "Ruby")
     
        data.m["PHP"] = "Laravel"
        data.order = append(data.order, "PHP")
     
        // Iterate these key/value pairs with order.
        for _, e := range data.order {
            fmt.Println(fmt.Sprintf("%s: %s", e, data.m[e]))
        }
    }
    

    藉由本文的介紹,相信各位讀者可以知道映射如何使用。由於映射相當實用,各位讀者可以多多練習,以熟悉映射的使用方式。

    你或許對以下產品有興趣