go語言學習筆記(第2章)—類型部分

第2章:順序編程 

GO語言被稱爲"更好的C語言"

1. 變量

1) 變量的聲明GO語言引入了關鍵字  var,而類型信息放在變量名以後

例如: var v1 int

能夠將多個變量聲明放在一塊兒,例如:
var (
        v1 int
        v2 string
)

2) 變量初始化有3種方式:
var v1 int = 10
var v2 = 10
v3 := 10

GO語言引入了新的符號(冒號和等號的組合  :=),用來表達同時進行變量聲明和初始化的工做
但若是 := 左側的變量已經被聲明過了,再使用這個符號編譯會出錯

var i int
i := 2     //這樣編譯會報錯

指定類型已經再也不是必須的,GO編譯器能夠從初始化表達式的右值推導出該變量應該聲明爲哪一種類型,這讓GO語言看起來有點像動態類型語言(GO語言其實是徹徹底底的靜態類型語言)

3) 聲明變量以後的賦值過程
var v10 int
v10 = 123

GO提供了多重賦值功能
好比交換i和j變量的語言,以前的語言都須要引入一箇中間變量,但GO能夠這樣作:
i, j = j, i

4) 匿名變量

2. 常量

在GO語言中,常量是指編譯期間就已知且不可改變的值。常量能夠是數值類型,布爾類型,字符串類型。

GO語言的字面常量更接近咱們天然語言中的常量概念,是無類型的。只要這個常量在相應類型的值域範圍內,就能夠做爲該類型的常量。好比-12,能夠賦值給int, uint, int32, float32...等

1) 常量定義
和C同樣,定義常量也是使用 const關鍵字

若是定義常量時沒有指定類型,那麼它與字面常量同樣,是無類型常量。

go語言學習筆記(第2章)—類型部分

2) 預約義常量
GO語言預約義了這些常量: true, false和iota
iota比較特殊,能夠被認爲是一個可被編譯器修改的常量,在每個const關鍵字出現時被重置爲0,而後在下一個const出現以前,每出現一次iota,其所表明的數字會自動增1

go語言學習筆記(第2章)—類型部分

若是兩個const的賦值語言的表達式是同樣的,那麼能夠省略後一個賦值表達式
go語言學習筆記(第2章)—類型部分

go語言學習筆記(第2章)—類型部分
上面兩個聲明是同樣

3) 枚舉
枚舉指一系列相關的常量,GO語言不支持衆多其餘語言支持的enum關鍵字
在const後跟一對圓括號的方式定義一組常量,這種定義法在GO語言中一般用於定義枚舉值。
go語言學習筆記(第2章)—類型部分

GO語言中,以大寫字母開頭的常量在包外可見,numberOfDays爲包內私有,其餘符號則可被其餘包訪問。

3.類型

GO語言內置如下基礎類型:
布爾類型:bool
整型:int8, byte, int16, int, uint, uintptr
浮點類型:float32, float64
複數類型:complex64, complex128
字符串:string
字符類型:rune
錯誤類型:error

GO語言支持如下複合類型:
指針(pointer),數組(array),切片(slice),字典(map), 通道(chan)
結構體(struct), 接口(interface)

在這些基礎類型之上GO還封裝了下面幾種類型:int, uint和uintptr等。這些類型的特色在於使用方便,但使用者不能對這些類型的長度作任何假設。對於常規的開發者來講,用int和uint就能夠了,不必用int8之類明確指定長度的類型,以避免致使移植困難。

1) 布爾類型
布爾類型不能接受其餘類型的賦值,不支持自動或強制的類型轉換。
go語言學習筆記(第2章)—類型部分

2) 整型
整型是全部編程語言裏最基礎的數據類型。
int 和 int32在GO語言裏被認爲是兩種不一樣的類型。編譯器也不會幫你自動作類型轉換
go語言學習筆記(第2章)—類型部分

使用強制類型轉換能夠解決這個編譯錯誤:
go語言學習筆記(第2章)—類型部分

數值運算
GO語言支持下面的常規整數運算:+, -, *, /和%  %和在C語言中同樣是求佘運算,好比:
5 % 3 //結果是2

比較運算
GO語言支持如下的幾種比較運算符:>, <, ==, >=, <=和 != 

兩個不一樣類型的整型數不能直接比較,好比int8 類型的數和int類型的數不能直接比較,但各類類型的整型變量均可以直接與字面常量進行比較

go語言學習筆記(第2章)—類型部分

位運算
GO語言的大多數位運算符與C語言都比較相似,除了取反在C語言中是~x,而在GO語言中是^x

3) 浮點型
浮點型用於表示包含小數點的數據。
GO語言定義了兩個類型float32, float64,其中float32等價於C語言中的float類型,float64等價於C語言的double類型
若是這樣定義浮點型: fvalue2 := 12.0 
其類型將被自動設爲float64,而無論賦給他的數字是否是用32位長度表示的

go語言學習筆記(第2章)—類型部分

由於浮點數不是一種精確的表達方式,因此像整型那樣直接用==來判斷兩個浮點數是否相等是不可行的,這可能會致使不穩定的結果。替代方案就是相減後差小於0.00001

4) 字符串
在GO語言中,字符串也是一種基本類型。
go語言學習筆記(第2章)—類型部分
字符串的內容能夠用相似於數組下標的方式獲取, 字符串的內容不能在初始化後被修改

GO語言中的Printf()函數的用法與C語言運行庫中的printf()函數一模一樣。

GO語言只支持UTF-8和Unicode編碼。對於其餘編碼,GO語言標準庫並無內置的編碼轉換支持。不過,所幸的使咱們能夠很容易基於iconv庫用Cgo包裝一個。

a. 字符串經常使用的操做有:字符串鏈接,字符串長度,取字符
go語言學習筆記(第2章)—類型部分

b. 字符串遍歷
GO語言支持兩種方式遍歷字符串。

go語言學習筆記(第2章)—類型部分

以Unicode字符方式遍歷時,每一個字符的類型是rune,而不是byte

4. 字符類型
在GO語言中支持兩個字符類型,一個是byte,表明UTF-8字符串的單個字節的值;另外一個是rune,表明單個Unicode字符

5. 數組
數組是GO語言中最經常使用的數據結構之一。
go語言學習筆記(第2章)—類型部分
在GO語言中,數組的長度在定義後就不可更改,在聲明時長度能夠爲一個常量或者一個常量表達式。
數組的長度是該數組類型的一個內置常量,能夠用GO語言的內置函數len()來獲取。

a. 元素訪問
使用數組下標來訪問數組中的元素,下標從0開始。 len(array) - 1則表示最後一個元素的下標。
GO語言提供了一個關鍵字 range,用於便捷地遍歷容器中的元素。數組也是range支持的範圍。
go語言學習筆記(第2章)—類型部分
range具備兩個返回值,第一個返回值是元素的數組下標,第二個返回值是元素的值。

b. 值類型
在GO語言中數組是一個值類型,全部的值類型變量在賦值和做爲參數傳遞時都將產生一次複製動做。若是將數組做爲函數的參數類型,則在函數調用時該參數將發生數據賦值。所以,在函數體中沒法修改傳入的數組的內容,由於函數內操做的只是所傳入數組的一個副本。

go語言學習筆記(第2章)—類型部分
modify()內操做的那個數組跟main()中傳入的數組是兩個不一樣的實例。
若是要在函數內操做外部的數據結構,可使用數組切片來達成這個目標。

6. 數組切片
數組的特色:數組的長度在定義以後沒法再次修改;數組是值類型,每次傳遞都將產生一份副本。

GO語言另外提供了數組切片(slice)來彌補數組的不足。初看起來,數組切片就像一個指向數組的指針,實際上它擁有本身的數據結構,而不只僅是個指針。數組切片的數據結構能夠抽象爲如下3個變量:
  • 一個指向原生數組的指針
  • 數組切片中的元素個數
  • 數組切片已分配的存儲空間
從底層實現的角度看,數組切片實際上仍然使用數組來管理元素。基於數組,數組切片添加了一系列管理功能,能夠隨時動態擴充存放空間,而且能夠被隨意傳遞而不會致使所管理的元素被重複複製。

a. 建立數組切片
建立數組切片的方法主要有兩種—基於數組和直接建立。

數組的建立以下:
go語言學習筆記(第2章)—類型部分

GO語言支持用  myArray[first:last]這樣的方式來基於數組生成一個數組切片,並且這個用法還很靈活,好比如下都是合法的:
mySlice = myArray[:]
mySlice = myArray[:5]
mySlice = myArray[5:]

直接建立: 並不是必定要事先準備一個數組才能建立數組切片。GO語言提供的內置函數make()能夠用於靈活地建立數組切片。
例子:
go語言學習筆記(第2章)—類型部分
固然,事實上還會有一個匿名數組被建立出來,只是不須要咱們操心而已。

b. 元素遍歷
操做數組元素的全部方法都適用於數組切片,好比數組切片也能夠按下標讀寫元素,用len()函數獲取元素個數,並支持使用range關鍵字來快速遍歷全部元素。
go語言學習筆記(第2章)—類型部分

c. 數組切片
可動態增減元素是數組切片比數組切片更爲強大的功能。與數組相比,數組切片多了一個存儲能力的概念,即元素個數和分配的空間能夠是兩個不一樣的值。合理的設置存儲能力的值,能夠大幅下降數組切片內部從新分配內存和搬送內存塊的頻率,從而大大提升程序性能。

假設你明確知道當前建立的數組切片最多可能須要存儲的元素個數爲50,那麼若是你設置的存儲能力小於50,好比20,那麼元素在超過20時,底層將會發生至少一次這樣的動做:從新分配一塊"夠大"的內存,而且須要把內容從原來的內存塊複製到新分配的內存塊,這會產生比較明顯的開銷。給"夠大"這兩個字加上引號的緣由是系統並不知道多大才是夠大,因此只是一個簡單的猜想。好比,將原有的內存空間擴大兩倍,但兩倍並不必定夠,因此以前提到的內存從新分配和內容複製的過程頗有可能發生屢次,從而明顯下降系統的總體性能。但若是你知道最大是50而且一開始就設置存儲能力爲50,那麼以後就不會發生這樣很是消耗CPU的動做,從而達到空間換時間的效果。

數組切片支持GO語言內置的cap()函數和len()函數,cap()函數返回的是數組切片分配的空間大小,而len()函數返回的是數組切片中當前所存儲的元素個數。

go語言學習筆記(第2章)—類型部分

在mySlice已包含的5個元素的後面繼續新增元素,可使用append()函數
go語言學習筆記(第2章)—類型部分
函數append()的第二個參數是一個不定參數,咱們能夠按本身需求添加若干個元素,甚至能夠直接將一個數組切片追加到另外一個數組切片的末尾:
go語言學習筆記(第2章)—類型部分

須要注意的是,在第二個參數mySlice2後面加了3個點,即一個省略號,若是沒有這個省略號的話,會有編譯錯誤,由於按append()的語義,從第二個參數起全部的參數都是待附加的元素。由於mySlice中的元素類型是int,因此直接傳遞mySlice2是行不通的。加上省略號至關於把mySlice2包含的全部元素打散後傳入。

上述調用等同於:
mySlice = append(mySlice, 8, 9, 10)

數組切片會自動處理存儲空間不足的問題。若是追加的內容長度超過當前已分配的存儲空間,數組切片會自動分配一塊足夠大的內存。

d. 基於數組切片建立數組切片
數組切片也能夠基於另外一個數組切片建立。
go語言學習筆記(第2章)—類型部分
有意思的是,選擇的oldSlice元素範圍甚至能夠超過所包含的元素個數,好比newSlice能夠基於oldSlice的前6個元素建立,雖然oldSlice只包含5個元素。只要這個選擇的範圍不超過oldSlice存儲能力(即cap()返回的值),那麼這個建立程序就是合法的。newSlice中超出oldSlice元素的部分都會填上0

e. 內容複製
數組切片支持GO語言的另外一個內置函數copy(),用於將內容從一個數組切片複製到另外一個數組切片。若是加入的兩個數組切片不同大,就會按其中較小的那個數組切片的元素個數進行復制。
go語言學習筆記(第2章)—類型部分

7. map
在GO語言中,使用map不須要引入任何庫,而且用起來很方便。

go語言學習筆記(第2章)—類型部分
a. 變量聲明
var myMap map[string] PersonInfo  
myMap是聲明的map變量名,string是鍵的類型,PersonInfo則是其中所存放的值類型。

b. 建立
使用GO語言內置的函數make()來建立一個新的map
myMap  = make(map[string] PersonInfo)
也能夠選擇是否在建立時指定該map的初始存儲能力,例如
myMap = make(map[string] PersonInfo, 100) //初始存儲能力爲100

也能夠建立並初始化map
myMap = map[string] PersonInfo{
"1234": PersonInfo{"1", "Jack", "Room 101, ..."},
}

c. 元素賦值
myMap["1234"] = PersonInfo {"1", "Jack", "Room 101, ..."}

d. 元素刪除
Go語言提供了一個內置函數delete(),用於刪除容器內的元素
delete(myMap, "1234") //從myMap中刪除鍵爲"1234"的鍵值對,若是"1234"鍵不存在,這個調用將什麼都不發生。若是傳入的map變量值是nil,調用將致使程序拋出異常。

e. 元素查找
在GO語言中,map的查找功能設計的很精巧。
判斷可否從map中獲取一個值的常規作法是:
(1) 聲明並初始化一個變量爲空
(2) 試圖從map中獲取相應鍵的值到該變量中
(3) 判斷該變量是否依舊爲空,若是爲空則表示map中沒有包含該變量

這種作法比較囉嗦。在GO語言中,從map中查找一個特定的鍵,能夠這樣實現:
value, ok := myMap["1234"]
if ok {  //找到了
    //處理找到的value值
}

判斷是否成功找到特定的鍵,不須要檢查取到的值是否爲nil,只需查看第二個返回值ok。

配合 := 操做符, 讓你的代碼沒有多餘的成分,看起來很是清晰易懂。
相關文章
相關標籤/搜索