# Day08 Go先歇一會-小教基本型別 昨天飆車導致今天沒料, 先歇一會,明天再來狂教基本物件。 Go基本型別非常的簡單容易: 主要用到的就以下幾項: 布林是 `bool` 整數是 `int` 字串是 `string` 當然還有其他種類: ## 布林 布林不是美國人,而是資料型態boolean(有講跟沒講一樣) 只有 `1 bit`,只能純放一個`0`或者`1`, 但在Go中Bool不能當`0`或`1`(不能拿來與數字比較), 只能拿作`true`或`false`使用。 ```go func main() { var b bool = false fmt.Println(b) if b == false{ fmt.Println("b is false") } } ``` ## 數字類 #### 【int】 #### 【int8】、【int16】、【int32】、【int64】 看名字一眼便知,一個是`8bit`、一個是`16bit`、一個是`32bit`,另一個是`64bit`, 很**佛**對不。 (逼不得已,別打我) 學校老師教得好,`8bit`排列組合有著`2的8次方`的可能性=>`256`種, 就是一個`byte`的大小,這可以聯想到`ASCII`。 因為256種可能性要均勻分配到正負數,~128~127 ```go func main() { var a int8 = 128; fmt.Print(a) } ``` `constant 128 overflows int8` 編譯器很佛的會提示你已經Overflow了, 不像有些語言編譯過了,出來卻不是預期的數字。 至於沒有數字的`int`是`int32`還是`int64`呢? 這要看機器的環境了。 #### 【uint】 #### 【uint8】、【uint16】、【uint32】、【uint64】 和`int`用法基本上相同,但為`unsigned`就是沒有正負符號,也就是只能代表正整數的意思。 也因為把正負號(在int中 第一個bit如為0代表數字為正、1為負)的bit省略下來,讓uint家族能容納的數字就多一倍啦,也就是`uint8`可以存`256種可能(數字0 ~ 255)`。 ```go func main() { var a uint = -32 fmt.Println(a) } ``` `constant -32 overflows uint` 給負數不接受直接報錯。 #### 【float32】、【float64】 ```go func main() { var a float64 = 1.23 fmt.Println(a) } ``` 通常都是拿精準度比較高的`float64`來使用, 畢竟小數會有誤差,**若需要乘乘除除**,使用`float32`誤差會比`float64`來的大許多。 Go語言中沒有`double`。 #### 【complex64】、【complex128】 複數。 較少會用到,不過內建有這種型別運算時非常的方便。 ``` func main() { var c complex64 = 3.1 + 2i fmt.Print(c) } ``` ## 【字串】 Go語言中沒有`char`的型別。 通常以`string`或`rune`來替代。 #### 【string】 ```go func main() { var s string = "Hello World" fmt.Println(s) } ``` 要注意的是,**string中的字無法改變** 那怎摸辦餒?常見辦法有以下: * 用string[0:1]直接串文字 * 用fmt.Sprint()串文字 * 用Slice[] Append方法來接文字 由於string中的文字沒辦法改,要創新的變數來接收。 #### 【byte】 Byte用法非常的多,登場通常都會搭配`Slice[]`, 後面還會出現再進階介紹。 ```go func main() { var b = []byte("0") fmt.Println(b) b = []byte("爆肝工程師的異世界安魂曲") fmt.Println(b) } /* result: [48] [231 136 134 232 130 157 229 183 165 231 168 139 229 184 171 231 154 132 231 149 176 228 184 150 231 149 140 229 174 137 233 173 130 230 155 178] */ ``` #### 【rune】 `rune`意思是`符號`,簡單理解為`UTF-8`中的一個字符。 因為Go語言預設使用`UTF-8`編碼, 而`UTF-8`編碼中的每個字元長度不是固定的,以`8bit`為基本單位長度,範圍為`1 ~ 4`個字節(1 byte ~ 4 bytes)。 ```go func main() { var r = []rune("0") fmt.Println(r) r = []rune("爆肝工程師的異世界安魂曲") fmt.Println(r) } /* result: [48] [29190 32925 24037 31243 24107 30340 30064 19990 30028 23433 39746 26354] */ ``` 像常用到的`ASCII`中的`英文`、`數字`在UTF-8中只佔一個 `byte(8bits)`, 而中文、韓文、日文一個字符則用到`2~3 bytes`不等。 ## rune【小坑注意】 所以就會出現下面這樣的狀況:長度到底是算`符號數`還是算`byte數`? 第一次看到 不曉得`rune`的人看到程式碼的輸出, 會覺得 乾,這三汶? ```go func main() { a := "Hi,世界" fmt.Println(a) n := 0 for range a{ n++ } fmt.Println(len(a)) fmt.Println(n) } /* result: Hi,世界 9 5 */ ``` 可以看到, 以`for range`迭代印出來的長度,就是老老實實的以`bytes`來計算, 而`len()`印出來的長度是`符號數`,每個文字都只算一個。