這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
繼數組array、切片slice和指標(pointer)、結構體(struct)之後,繼續Go的複合類型。
字典(map)
Go的字典類型類似於Java的Map,python的Dictionary,都是一種無序的索引值對的集合。可以通過鍵(key)來檢索資料。
先看一個例子:
package mainimport "fmt"func main() { map1 := map[string]string{"1": "s"} fmt.Println("map1:", map1) map1["1"] = "www" fmt.Println("map1:", map1) var map2 map[string]string map2 = make(map[string]string) fmt.Println("map2:", map2) map2["1"] = "s" fmt.Println("map2:", map2) str, ok := map1["1"] if ok { fmt.Println("str:", str) }}
這個簡單的例子基本上包含了map的基本用法,包括聲明,賦值,取值等。
聲明,初始化
單是map的聲明和其他類型的變數聲明類似。
var map_variable map[keytype]valuetype//聲明 一個map類型的變數,key和value的類型是stringvar map2 map[string]string
單是聲明map變數如果不初始化map的話,那麼就會建立一個 nil map,預設值是 nil。nil map不能用來存放索引值對。
package mainimport "fmt"func main() { var myMap map[string]string fmt.Println(myMap == nil) myMap["1"] = "11" fmt.Println("myMap:", myMap)}
初始化的方法也有兩種,可以直接初始化或者使用Go語言內建的函數make()來建立一個新map,這個和切片基本一樣。
//定義是初始化賦值map1 := map[string]string{"1": "s"}//使用make函數初始化var map2 map[string]stringmap2 = make(map[string]string)
元素賦值和修改
賦值過程非常簡單明了,就是將鍵和值用下面的方式對應起來即可:
map2["1"] = "s"
這樣就給map類型的變數map2的key值為1的kery賦值為s。
通過上面的程式執行結果可以看出,如果key值已存在會更新key對應的值;若key不存在,則會早map裡增加key值,並賦值。
元素尋找
Go中,尋找map中是否存在某個值是通過雙賦值檢測某個鍵是否存在。
vlaue, ok := map[key]
若key在map中,ok 為true;否則,ok 為false 。
若key不存在,那麼vlaue 是該map元素類型的預設值。即如果map的value對應類型的預設值。
同樣的,當從map中讀取某個不存在的鍵時,結果是map的元素類型的預設值。
這樣判斷是否成功找到特定的鍵,不需要檢查取到的值是否為nil,只需查看第二個傳回值ok,代碼錶達更簡潔。
元素刪除
對於map元素的刪除,Go提供了一個內建函數delete()。
delete(myMap, "1")
這樣就把myMap中鍵為“1”的索引值對刪除。如果“1”這個鍵不存在,那麼這個調 用將什麼都不發生。
package mainimport "fmt"func main() { myMap := map[string]string{"1": "a", "2": "b"} fmt.Println("myMap:", myMap) delete(myMap, "1") fmt.Println("myMap:", myMap) delete(myMap, "3") fmt.Println("myMap:", myMap)}
其他類型
一下類型只做概念性介紹,因為涉及的東西比較深入,目前我也是初學,體會不出太深刻的東西。
通道(chan)
通道是串連並發夠程的管道。並發編程是個很大的論題,因此這裡只是大致說一點,希望可以以此看出Go在並發編程裡的優勢。詳細的內容,需要在以後使用中慢慢瞭解。
在並發編程中,為實現對共用變數的正確訪問需要精確的控制,這在多數環境下都很困難。 Go語言另闢蹊徑,它將共用的值通過通道傳遞,實際上,多個獨立執行的線程從不會主動共用。 在任意給定的時間點,只有一個Go程能夠訪問該值。資料競爭從設計上就被杜絕了。 為了提倡這種思考方式,Go將它簡化為一句口號:
不要通過共用記憶體來通訊,而應通過通訊來共用記憶體。
Go程的概念:Go程在多線程作業系統上可實現多工,因此若一個線程阻塞,比如說等待I/O, 那麼其它的線程就會運行。Go程的設計隱藏了線程建立和管理的諸多複雜性。
在函數或方法前添加 go 關鍵字能夠在新的Go程中調用它。當調用完成後, 該Go程也會安靜地退出。有點像Unix Shell中的 & 符號,它能讓命令在後台運行。
介面(interface)
對於介面的概念Go應該也其他支援介面的程式設計語言差別不大。
Go中的介面為指定對象的行為提供了一種方法:如果某樣東西可以完成這個, 那麼它就可以用在這裡。
若某種現有的類型僅實現了一個介面,且除此之外並無可匯出的方法,則該類型本身就無需匯出。 僅匯出該介面能讓我們更專註於其行為而非實現,其它屬性不同的實現則能鏡像該原始類型的行為。
錯誤類型(error)
錯誤處理應該是任何程式設計語言都該涉及好的功能,Go也不例外。
Go語言的多值返回特性, 使得它在返回常規的值時,還能輕鬆地返回詳細的錯誤描述。按照約定,錯誤的類型通常為 error,這是一個內建的簡單介面。
type error interface { Error() string}
可以輕鬆實現這個介面以實現這樣不僅能看見錯誤, 還能提供一些上下文。