iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
1
Software Development

Go繁不及備載系列 第 8

# Day08 Go先歇一會-小教基本型別(bool, int, string, rune)

  • 分享至 

  • xImage
  •  

Day08 Go先歇一會-小教基本型別

昨天飆車導致今天沒料,
先歇一會,明天再來狂教基本物件。

Go基本型別非常的簡單容易:

主要用到的就以下幾項:
布林是 bool
整數是 int
字串是 string
當然還有其他種類:

布林

布林不是美國人,而是資料型態boolean(有講跟沒講一樣)
只有 1 bit,只能純放一個0或者1
但在Go中Bool不能當01(不能拿來與數字比較),
只能拿作truefalse使用。

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

func main() {
	var a int8 = 128;
	fmt.Print(a)
}

constant 128 overflows int8
編譯器很佛的會提示你已經Overflow了,
不像有些語言編譯過了,出來卻不是預期的數字。

至於沒有數字的intint32還是int64呢?
這要看機器的環境了。

【uint】

【uint8】、【uint16】、【uint32】、【uint64】

int用法基本上相同,但為unsigned就是沒有正負符號,也就是只能代表正整數的意思。
也因為把正負號(在int中 第一個bit如為0代表數字為正、1為負)的bit省略下來,讓uint家族能容納的數字就多一倍啦,也就是uint8可以存256種可能(數字0 ~ 255)

func main()  {
	var a uint = -32
	fmt.Println(a)
}

constant -32 overflows uint
給負數不接受直接報錯。

【float32】、【float64】

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的型別。
通常以stringrune來替代。

【string】

func main() {
	var s string = "Hello World"
	fmt.Println(s)
}

要注意的是,string中的字無法改變
那怎摸辦餒?常見辦法有以下:

  • 用string[0:1]直接串文字
  • 用fmt.Sprint()串文字
  • 用Slice[] Append方法來接文字

由於string中的文字沒辦法改,要創新的變數來接收。

【byte】

Byte用法非常的多,登場通常都會搭配Slice[]
後面還會出現再進階介紹。

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)。

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的人看到程式碼的輸出,
會覺得 乾,這三汶?

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()印出來的長度是符號數,每個文字都只算一個。


上一篇
# Day07 Go飆車囉-狂教基本語法(if, switch, for, log)
下一篇
# Day09 Go繼續開車-基本組合型別(array, slice)
系列文
Go繁不及備載35
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
ok3201123
iT邦新手 5 級 ‧ 2021-12-30 08:44:57

最後好像反了
看起來len()印出來的是Bytes數
for range迭代的n才是文字數

我要留言

立即登入留言