map
在 C++/java中,map一般都以庫的方式提供,比如在 C++中是 STL的 std::map<>,在 C#中是 Dictionary<>,在java中 HashMAP<>,在這些語言中,如果要使用 map就必須要先引入相應的庫,而在 go 中,則不需要引入任何庫,适用也比較友善
map是一堆鍵值對的未排序集合,比如一身份證作為唯一鍵來表示一個人的資訊,則這個 map 可以定義成這個樣子:
func main() {
//personDB 是聲明的map變量名,string是鍵的類型,PersonInfo則是存放的類型
var personDB map[string] PersonInfo
//這裡我們使用 make() 内置函數建立了一個新的 map() 下面是指建立了一個鍵類型為 string,值類型為 PersonInfo 的 map
personDB = make(map[string] PersonInfo)
//添加資訊
personDB["412725"] = PersonInfo{"123","zhangsan","beijing"}
personDB["412725333"] = PersonInfo{"123","lisi","nanjing"}
//判斷是否存在鍵為 412725 如果存在 ok 的值為 true 不存在則反之
person, ok := personDB["412725"]
if ok {
fmt.Println("this here",person)
//從 PersonDB 中删除這個鍵為 412725 的元素,加入這個鍵并不存在,那麼這個調用什麼都不會發生,也不會存在什麼副作用
//如果我們傳入的 map 變量的值為 nil 則會抛出一個異常
delete(personDB, "412725")
}else {
fmt.Println("is not here")
}
for i, v := range personDB {
fmt.Println("鍵是:",i,"/t對應的值是:",v)
}
}
輸出資訊:
this here {123 zhangsan beijing}
鍵是: 412725333 /t對應的值是: {123 lisi nanjing}
從最後我們的變量可以看出 map中是存在:412725 這個鍵的,這個時候 ok 的值為 true,走進 if 裡,執行了 delete(),最後我們的列印可以看出,這個元素已經被成功删除!
這裡多說一點,另一種建立 map 直接初始化的方法,如下:
myMap = map[string] PersonInfo{
"1234": PersonInfo{"1", "Jack", "Room 101,..."},
...
...
...
}
map中的元素查找
go語言中,map的查找功能設計的比較精巧,其他語言中,加入我們判斷能否擷取到一個值不是一件容易的事情,判斷能否從 map 中擷取一個值的正常做法是:
- 聲明并且初始化一個變量為空
- 試圖從 map 中擷取對應的鍵的值到該變量中
- 判斷該變量是否為空,如果為空,則表示 map 中不存在該變量
這種用法比較啰唆,而且判斷變量是否為空這條語句并不能真正表意(是否成功取到對應的
值),進而影響代碼的可讀性和可維護性。有些庫甚至會設計為因為一個鍵不存在而抛出異常,
讓開發者用起來膽戰心驚,不得不一層層嵌套try-catch語句,這更是不人性化的設計。在Go
語言中,要從map中查找一個特定的鍵,可以通過下面的代碼來實作:
value, ok := myMap["1234"]
if ok { // 找到了
// 處理找到的value
}
判斷是否成功找到特定的鍵,不需要檢查取到的值是否為nil,隻需檢視第二個傳回值ok,
這讓表意清晰很多。配合:=操作符,讓你的代碼沒有多餘成分,看起來非常清晰易懂