-
通道(Channel)是Go語言中一種非常獨特的數據結構。它可用于在不同Goroutine之間傳遞類型化的數據,并且是并發安全的。相比之下,其他類型都不是并發安全的。 Goroutine(也稱為Go程序)可以被看做是承載可被并發執行的代碼塊的載體。 它們由Go語言的運行時系統調度,并依托操作系統線程(又稱內核線程)來并發地執行其中的代碼塊。 通道類型僅由兩部分組成,如:chan T 在這個類型字面量中,左邊是代表通道類型的關鍵字chan,而右邊則是一個可變的部分,即代表該通道類型允許傳遞的數據的類型(或稱通道的元素類型)。這兩部分之間需要以空格分隔。 與其它的數據類型不同,我們無法表示一個通道類型的值。因此,我們也無法用字面量來為通道類型的變量賦值。 我們只能通過調用內建函數make來達到目的。 make函數可接受兩個參數。第一個參數是代表了將被初始化的值的類型的字面量(比如chan int),而第二個參數則是值的長度。 例如,初始化一個長度為5且元素類型為int的通道值,則需要這樣寫:make(chan int, 5) make函數也可以被用來初始化切片類型或字典類型的值。 通道值的長度應該被稱為其緩存的尺寸,它代表著通道值中可以暫存的數據的個數。 注意,暫存在通道值中的數據是先進先出的,即:越早被放入(或稱發送)到通道值的數據會越先被取出(或稱接收)。 聲明一個通道類型的變量,并為其賦值:ch1 := make(chan string, 5) 使用接收操作符<-向通道值發送數據,也可以使用它從通道值接收數據。 例如,向通道ch1發送字符串"value1",應該這樣做:ch1 <- "value1" 從ch1那里接收字符串,則要這樣:<- ch1 ,可以直接把接收到的字符串賦給一個變量,如:value := <- ch1 針對通道值的接收操作也可以有第二個結果值,如:value, ok := <- ch1 這樣做的目的是為了消除與零值有關的歧義。這里的變量ok的值同樣是bool類型的。它代表了通道值的狀態,true代表通道值有效,而false則代表通道值已無效(或稱已關閉)。 調用內建函數close來關閉通道值,就像這樣:close(ch1) 通道類型屬于引用類型。它的零值即為nil。查看全部
-
Go語言的字典(Map)類型其實是哈希表(Hash Table)的一個實現。 字典用于存儲鍵-元素對(更通俗的說法是鍵-值對)的無序集合。 注意,同一個字典中的每個鍵都是唯一的。 字典類型的字面量如下: map[K]T 其中,“K”意為鍵的類型,而“T”則代表元素(或稱值)的類型。 如果我們要描述一個鍵類型為int、值類型為string的字典類型的話,應該這樣寫:map[int]string 字典的鍵類型必須是可比較的,否則會引起錯誤。鍵類型不能是切片、字典或函數類型。 每個鍵值對的鍵和值之間由英文冒號分隔。以字典類型map[int]string為例,它的值的字面量可以是這樣的: map[int]string{1: "a", 2: "b", 3: "c"} 我們可以把這個值賦給一個變量: mm := map[int]string{1: "a", 2: "b", 3: "c"} 然后運用索引表達式取出字典中的值,就像這樣: b := mm[2] 也可以利用索引表達式來賦值,比如這樣: mm[2] = b + "2" 這使得字典mm中與鍵2對應的值變為了"b2"。 現在我們再來向mm添加一個鍵值對: mm[4] = "" 之后,在從中取出與`4`和`5`對應的值: d := mm[4] e := mm[5] 此時,變量d和e的值都會是多少呢?答案是都為"",即空字符串。 但是mm[5]的求值結果為什么也是空字符串呢? 原因是,在Go語言中有這樣一項規定,即:對于字典值來說, 如果其中不存在索引表達式欲取出的鍵值對,那么就以它的值類型的空值(或稱默認值)作為該索引表達式的求值結果。由于字符串類型的空值為"",所以mm[5]的求值結果即為""。 Go語言為我們提供了另外一個寫法,即: e, ok := mm[5] 針對字典的索引表達式可以有兩個求值結果。第二個求值結果是bool類型的。 它用于表明字典值中是否存在指定的鍵值對。 在上例中,變量ok必為false。因為mm中不存在以5為鍵的鍵值對。 從字典中刪除鍵值對的方法是調用內建函數delete,如: delete(mm, 4) 無論mm中是否存在以4為鍵的鍵值對,delete都會“無聲”地執行完畢?!坝袆t刪除,無則不做”。 字典類型屬于引用類型。它的零值即為nil。查看全部
-
package main import "fmt" func main() { //定義一個切片 var numbers4 = [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} //為切片設置容量上界值為8 slice5 := numbers4[4:6:8] //4是元素下界索引,6是元素上界索引,8是容量上界值 length := (2) //5,6 長度 capacity := (4) //容量 5,6,7,8 fmt.Printf("切片slice5長度:%d\n", len(slice5)) fmt.Printf("切片slice5容量:%d\n", cap(slice5)) fmt.Printf("%v, %v\n", length == len(slice5), capacity == cap(slice5)) //將其長度延展得與其容量相同 slice5 = slice5[:cap(slice5)] //切片追加方法 slice5 = append(slice5, 11, 12, 13) //5,6,7,8,11,12,13 length = (7) fmt.Printf("%v\n", length == len(slice5)) for i := 0; i < len(slice5); i++ { fmt.Printf("切片的第%d個值是:%d\n", i, slice5[i]) } //定義一個切片 //slice5 := []int[5,6,7,8,11,12,13] slice6 := []int{0, 0, 0} //切片復制方法 把第二個參數值中的元素復制到第一個參數值中的相應位置上 copy(slice5, slice6) //0,0,0,8,11,12,13 e2 := (0) e3 := (8) e4 := (11) fmt.Printf("%v, %v, %v\n", e2 == slice5[2], e3 == slice5[3], e4 == slice5[4]) }查看全部
-
在進行“切片”操作的時候需要指定元素下界索引和元素上界索引,就像這樣:numbers3[1:4] 在方括號中放入第三個正整數,如numbers3[1:4:4] 這第三個正整數被稱為容量上界索引。 換句話說,它可以限制我們通過這個切片值對其底層數組中的更多元素的訪問。 在上一節講到的numbers3和slice1。針對它們的賦值語句是這樣的: var numbers3 = [5]int{1, 2, 3, 4, 5} var slice1 = numbers3[1:4] 這時,變量slice1的值是[]int{2, 3, 4}。 但是我們可以通過如下操作將其長度延展得與其容量相同: slice1 = slice1[:cap(slice1)] 通過此操作,變量slice1的值變為了[]int{2, 3, 4, 5},且其長度和容量均為4。 現在,numbers3的值中的索引值在[1,5)范圍內的元素都被體現在了slice1的值中。 這是以numbers3的值是slice1的值的底層數組為前提的。 如果我們在切片表達式中加入了第三個索引(即容量上界索引),如: var slice1 = numbers3[1:4:4] 那么在這之后,無論我們怎樣做都無法通過slice1訪問到numbers3的值中的第五個元素。 因為這超出了我們剛剛設定的slice1的容量。 這需要使用到內建函數append。append會對切片值進行擴展并返回一個新的切片值。 使用方法如下:slice1 = append(slice1, 6, 7) 通過上述操作,slice1的值變為了[]int{2, 3, 4, 6, 7}。 注意,一旦擴展操作超出了被操作的切片值的容量,那么該切片的底層數組就會被自動更換。 這也使得通過設定容量上界索引來對其底層數組進行訪問控制的方法更加嚴謹了。 切片值的“復制”函數是調用copy函數。 該函數接受兩個類型相同的切片值作為參數,并會把第二個參數值中的元素復制到第一個參數值中的相應位置(索引值相同)上。 這里有兩點需要注意: 1. 這種復制遵循最小復制原則,即:被復制的元素的個數總是等于長度較短的那個參數值的長度。 2. 與append函數不同,copy函數會直接對其第一個參數值進行修改。查看全部
-
字符串的表示法有兩種,即:原生表示法和解釋型表示法。若用原生表示法,需用反引號“`”把字符序列包裹起來。若用解釋型表示法,則需用雙引號“"”包裹字符序列。 二者的區別是,前者表示的值是所見即所得的(除了回車符)。在那對反引號之間的內容就是該字符串值本身。而后者所表示的值中的轉義符會起作用并在程序編譯期間被轉義。所以,如此表示的字符串值的實際值可能會與我們看到的表象不相同。 ------------解釋型-表示法,是什么意思呢?查看全部
-
切片(Slice)與數組不同的是,無法通過切片類型來確定其值的長度。每個切片值都會將數組作為其底層數據結構。我們也把這樣的數組稱為切片的底層數組。 切片類型的字面量如:[]int 或[]string 不同長度的切片值是有可能屬于同一個類型的。而不同長度的數組值必定屬于不同類型。切片類型的聲明:type MySlice []int 類型MySlice即為切片類型[]int的一個別名。切片值的表示:[]int{1, 2, 3} 我們在上一節講到的操作數組值的方法同樣適用于切片值。不過,還有一種操作數組值的方法我們沒講到。這種操作的名稱就叫“切片”,如: var numbers3 = [5]int{1, 2, 3, 4, 5} var slice1 = numbers3[1:4] 切片表達式( 第二條賦值語句中在“=”右邊部分)一般由(numbers3有三種可能)字符串、數組或切片的值以及由方括號包裹由英文冒號“:”分隔的兩個正整數組成。這兩個正整數分別表示元素下界和上界索引。在本例中,切片表達式numbers3[1:4]的求值結果為[]int{2, 3, 4}??梢姡衅磉_式的求值結果相當于以元素下界和上界索引作為依據從被操作對象上“切下”而形成的新值。被“切下”的部分不包含上界索引指向的元素。另外,切片表達式的求值結果會是切片類型的,且其元素類型與被“切片”的值的元素類型一致 我們也可以在一個切片值上實施切片操作。操作的方式與上述無異。如: var slice2 = slice1[1:3] slice2的值為[]int{3, 4}。注意,作為切片表達式求值結果的切片值的長度總是為元素上界索引與元素下界索引的差值len(slice2)即上例的3-1 除了長度,切片值以及數組值還有另外一個屬性——容量。數組值的容量總是等于其長度。而切片值的容量則往往與其長度不同 一個切片值的容量即為它的第一個元素值在其底層數組中的索引值與該數組長度的差值的絕對值。獲取數組、切片或通道類型的值的容量,我們可以使用內建函數cap,如: var capacity2 int = cap(slice2) 最后,要注意,切片類型屬于引用類型。它的零值為nil,即空值。如果我們只聲明一個切片類型的變量而不為它賦值,那么該變量的值將會是nil。例如: var slice3 []int 它的值是nil查看全部
-
Go語言-數組類型 一個數組(Array)就是一個可以容納若干類型相同的元素的容器。這個容器的大?。磾到M的長度)是固定的。比如,聲明了一個數組類型:type MyNumbers [3]int 注:類型聲明語句由關鍵字type、類型名稱和類型字面量組成。 類型字面量用于表示某個類型的字面表示(或稱標記方法)。用于表示某個類型的值的字面表示被稱為值字面量或字面量。 類型字面量[3]int由兩部分組成。第一部分是由方括號包裹的數組長度,即[3]。數組的長度是固定不變的。第二個組成部分是int表示數組可以容納的元素類型。我們可以把MyNumbers當做數組類型[3]int來使用。 在表示一個數組類型的值時,應該把該類型的類型字面量寫在最左邊,然后用花括號包裹該值包含的若干元素。各元素之間以(英文半角)逗號分隔,即: [3]int{1, 2, 3} 把該數組字面量賦給一個名為numbers的變量:var numbers = [3]int{1, 2, 3} 注:這是一條變量聲明語句。它在聲明變量的同時為該變量賦值。 另一種方法是,可以省略類型字面量的長度,像這樣: var numbers = [...]int{1, 2, 3} 使用索引表達式來訪問該數組的任何一個元素,例如: numbers[0] // 會得到第一個元素 numbers[1] // 會得到第二個元素 注:索引表達式由字符串、數組、切片或字典類型的值(或者代表此類值的變量或常量)和由方括號包裹的索引值組成。在這里,索引值的有效范圍是[0, 3)。對于數組來說,索引值既不能小于0也不能大于或等于數組值的長度。索引值的最小有效值總是0,而不是1。 要想修改數組值中的某一個元素值,可以使用賦值語句。例如要修改numbers中的第二個元素可以這樣:numbers[1] = 4 獲取數組長度的方法:len(數組名) var length = len(numbers) 注:len是Go語言的內建函數的名稱。該函數用于獲取字符串、數組、切片、字典或通道類型的值的長度。我們可以在Go語言源碼文件中直接使用它。 如果只聲明一個數組類型的變量而不為它賦值,那么需要指定這個數組的長度,數組的每個值將會使用默認值0表示。如: var numbers2 [5]int 則它的值會是 [5]int{0, 0, 0, 0, 0}查看全部
-
Go語言-字符串類型 一個字符串類型的值可以代表一個字符序列。這些字符必須是被Unicode編碼規范支持的。從表象上來說是字符序列,但是在底層,一個字符串值卻是由若干個字節來表現和存儲的。 一個字符串(也可以說字符序列)會被Go語言用Unicode編碼規范中的UTF-8編碼格式編碼為字節數組。 在一個字符串值或者一個字符串類型的變量之上應用Go語言的內置函數len將會得到代表它的那個字節數組的長度。這可能與我們看到的表象是不同的。 字符串的表示法有兩種,即:原生表示法和解釋型表示法。 若用原生表示法,需用反引號“`”把字符序列包裹起來。 若用解釋型表示法,則需用雙引號“"”包裹字符序列。 二者的區別是,前者表示的值是所見即所得的(除了回車符)。在那對反引號之間的內容就是該字符串值本身。而后者所表示的值中的轉義符會起作用并在程序編譯期間被轉義。所以,如此表示的字符串值的實際值可能會與我們看到的表象不相同。 注意,字符串值是不可變的。一旦創建了一個字符串類型的值,就不可能再對它本身做任何修改。查看全部
-
byte與rune byte與rune類型有一個共性,即:它們都屬于別名類型。byte是uint8的別名類型,而rune則是int32的別名類型。 byte類型的值需用8個比特位表示,其表示法與uint8類型無異。 一個rune類型的值即可表示一個Unicode字符。 Unicode是一個可以表示世界范圍內的絕大部分字符的編碼規范。關于它的詳細信息,大家可以參看其官網(http://unicode.org/)上的文檔,或在Google上搜索。 用于代表Unicode字符的編碼值也被稱為Unicode代碼點。一個Unicode代碼點通常由“U+”和一個以十六進制表示法表示的整數表示。例如,英文字母“A”的Unicode代碼點為“U+0041”。 rune類型的值需要由單引號“'”包裹。例如,'A'或'郝'。這種表示方法一目了然。不過,我們還可以用另外幾種形式表示rune類型值。 在rune類型值的表示中支持幾種特殊的字符序列,即:轉義符。它們由“\”和一個單個英文字符組成。查看全部
-
Go語言-復數類型 復數類型同樣有兩個,即complex64和complex128。存儲這兩個類型的值的空間分別需要8個字節和16個字節。 實際上,complex64類型的值會由兩個float32類型的值分別表示復數的實數部分和虛數部分。而complex128類型的值會由兩個float64類型的值分別表示復數的實數部分和虛數部分。 復數類型的值一般由浮點數表示的實數部分、加號“+”、浮點數表示的虛數部分,以及小寫字母“i”組成。比如,3.7E+1 + 5.98E-2i。 正因為復數類型的值由兩個浮點數類型值組成,所以其表示法的規則自然需遵從浮點數類型的值表示法的相關規則。查看全部
-
浮點數類型有兩個,即float32和float64。存儲這兩個類型的值的空間分別需要4個字節和8個字節。 浮點數類型的值一般由整數部分、小數點“.”和小數部分組成。其中,整數部分和小數部分均由10進制表示法表示。另一種表示方法就是加入指數部分。指數部分由“E”或“e”以及一個帶正負號的10進制數組成。 比如,3.7E-2表示浮點數0.037。又比如,3.7E+1表示浮點數37。 浮點數類型值的表示也可以被簡化。比如,37.0可以被簡化為37。又比如,0.037可以被簡化為.037。 在Go語言里,浮點數的相關部分只能由10進制表示法表示,而不能由8進制表示法或16進制表示法表示。比如,03.7表示的一定是浮點數3.7。查看全部
-
輸出時%X表示16進制,%d表示10進制 16進制: 它由0-9,A-F組成,字母不區分大小寫 與10進制的對應關系是:0-9對應0-9;A-F對應10-15 N進制的數可以用0~(N-1)的數表示,超過9的用字母A-F 1.數值變量賦值,int類型默認是10進制表示, var num1 int = 10 (默認10進制) var num1 int = 010 (使用8進制表示,前綴是 0表示) var num1 int = 0xC (使用16進制表示,前綴是0x)查看全部
-
Go語言的整數類型一共有10個。 其中計算架構相關的整數類型有兩個,即:有符號的整數類型int和無符號的整數類型uint。 size:=是賦值,專用術語叫“短變量聲明”。這種聲明并賦值的方式會省略關鍵字“var”和被賦值的變量的類型,這也是“短”的由來。 一個字節等于8bit查看全部
-
go語言使用var關鍵字定義變量,使用const關鍵字定義常量。 賦值 1、var num1 int = 1 2、var num1,num2 int = 1,2 3、var {num2 int = 4 num1 int =6 num3 int =7} 4、var {num1 int num2 int num3 int} num1,num2,num3 = 1,2,3查看全部
-
工作區是放置Go源碼文件的目錄;一般情況下,Go源碼文件都需要存放到工作區中;但是對于命令源碼文件來說,這不是必須的。 每一個工作區的結構都類似下圖所示:/home/hypermind/golib: src/ pkg/ bin/ src目錄用于存放源碼文件;以代碼包為組織形式 pkg目錄用于存放歸檔文件(名稱以.a為后綴的文件) 所有歸檔文件都會被存放到該目錄下的平臺相關目錄中,用樣以代碼包為組織形式 平臺相關目錄:兩個隱含的Go語言環境變量:GOOS(操作系統)和GOARCH(計算機架構)。以$GOOS_$GOPATH為命名方式,如:linux_amd64 <工作區目錄>/pkg/<平臺相關目錄>/<一級代碼包>/<二級代碼包>/<末級代碼包>.a bin目錄:用于存放當前工作區中的Go程序的可執行文件 1.當環境變量GOBIN已有效設置時,該目錄會變的無意義;當GOPATH的值中包含多個工作區的路徑時,必須設置GOBIN,否則無法成功安裝Go程序的可執行文件查看全部
舉報
0/150
提交
取消