Hi,大家好。
我是明哥,在自己學習 Golang 的這段時間里,我寫了詳細的學習筆記放在我的個人微信公眾號 《Go編程時光》,對於 Go 語言,我也算是個初學者,因此寫的東西應該會比較適合剛接觸的同學,如果你也是剛學習 Go 語言,不防關注一下,一起學習,一起成長。
我的在線博客:http://golang.iswbm.com
我的 Github:github.com/iswbm/GolangCodingTime
1. byte 與 rune
byte,占用1個節字,就 8 個比特位,所以它和 uint8
類型本質上沒有區別,它表示的是 ACSII 表中的一個字符。
如下這段代碼,分別定義了 byte 類型和 uint8 類型的變量 a 和 b
import "fmt"
func main() {
var a byte = 65
// 8進制寫法: var c byte = '\101' 其中 \ 是固定前綴
// 16進制寫法: var c byte = '\x41' 其中 \x 是固定前綴
var b uint8 = 66
fmt.Printf("a 的值: %c \nb 的值: %c", a, b)
// 或者使用 string 函數
// fmt.Println("a 的值: ", string(a)," \nb 的值: ", string(b))
}
在 ASCII 表中,由於字母 A 的ASCII 的編號為 65 ,字母 B 的ASCII 編號為 66,所以上面的代碼也可以寫成這樣
import "fmt"
func main() {
var a byte = 'A'
var b uint8 = 'B'
fmt.Printf("a 的值: %c \nb 的值: %c", a, b)
}
他們的輸出結果都是一樣的。
a 的值: A
b 的值: B
rune,占用4個字節,共32位比特位,所以它和 uint32
本質上也沒有區別。它表示的是一個 Unicode字符(Unicode是一個可以表示世界范圍內的絕大部分字符的編碼規范)。
import (
"fmt"
"unsafe"
)
func main() {
var a byte = 'A'
var b rune = 'B'
fmt.Printf("a 占用 %d 個字節數\nb 占用 %d 個字節數", unsafe.Sizeof(a), unsafe.Sizeof(b))
}
輸出如下
a 占用 1 個字節數
b 占用 4 個字節數
由於 byte 類型能表示的值是有限,只有 2^8=256 個。所以如果你想表示中文的話,你只能使用 rune 類型。
var name rune = '中'
或許你已經發現,上面我們在定義字符時,不管是 byte 還是 rune ,我都是使用單引號,而沒使用雙引號。
對於從 Python 轉過來的人,這里一定要注意了,在 Go 中單引號與 雙引號並不是等價的。
單引號用來表示字符,在上面的例子里,如果你使用雙引號,就意味着你要定義一個字符串,賦值時與前面聲明的前面會不一致,這樣在編譯的時候就會出錯。
cannot use "A" (type string) as type byte in assignment
上面我說了,byte 和 uint8 沒有區別,rune 和 uint32 沒有區別,那為什么還要多出一個 byte 和 rune 類型呢?
理由很簡單,因為uint8 和 uint32 ,直觀上讓人以為這是一個數值,但是實際上,它也可以表示一個字符,所以為了消除這種直觀錯覺,就誕生了 byte 和 rune 這兩個別名類型。
2. 字符串
字符串,可以說是大家很熟悉的數據類型之一。定義方法很簡單
var mystr string = "hello"
上面說的byte 和 rune 都是字符類型,若多個字符放在一起,就組成了字符串,也就是這里要說的 string 類型。
比如 hello
,對照 ascii 編碼表,每個字母對應的編號是:104,101,108,108,111
import (
"fmt"
)
func main() {
var mystr01 sting = "hello"
var mystr02 [5]byte = [5]byte{104, 101, 108, 108, 111}
fmt.Printf("mystr01: %s\n", mystr01)
fmt.Printf("mystr02: %s", mystr02)
}
輸出如下,mystr01 和 mystr02 輸出一樣,說明了 string 的本質,其實是一個 byte數組
mystr01: hello
mystr02: hello
通過以上學習,我們知道字符分為 byte 和 rune,占用的大小不同。
這里來考一下大家,hello,中國
占用幾個字節?
要回答這個問題,你得知道 Go 語言的 string 是用 uft-8 進行編碼的,英文字母占用一個字節,而中文字母占用 3個字節,所以 hello,中國
的長度為 5+1+(3*2)= 12個字節。
import (
"fmt"
)
func main() {
var country string = "hello,中國"
fmt.Println(len(country))
}
// 輸出
12
以上雖然我都用雙引號表示 一個字符串,但這並不是字符串的唯一表示方式。
除了雙引號之外 ,你還可以使用反引號。
大多情況下,二者並沒有區別,但如果你的字符串中有轉義字符\
,這里就要注意了,它們是有區別的。
使用反引號號包裹的字符串,相當於 Python 中的 raw 字符串,會忽略里面的轉義。
比如我想表示 \r\n
這個 字符串,使用雙引號是這樣寫的,這種叫解釋型表示法
var mystr01 string = "\\r\\n"
而使用反引號,就方便多了,所見即所得,這種叫原生型表示法
var mystr02 string = `\r\n`
他們的打印結果 都是一樣的
import (
"fmt"
)
func main() {
var mystr01 string = "\\r\\n"
var mystr02 string = `\r\n`
fmt.Println(mystr01)
fmt.Println(mystr02)
}
// output
\r\n
\r\n
如果你仍然想使用解釋型的字符串,但是各種轉義實在太麻煩了。你可以使用 fmt 的 %q
來還原一下。
import (
"fmt"
)
func main() {
var mystr01 string = `\r\n`
fmt.Println(`\r\n`)
fmt.Printf("的解釋型字符串是: %q", mystr01)
}
輸出如下
\r\n
的解釋型字符串是: "\\r\\n"
同時反引號可以不寫換行符(因為沒法寫)來表示一個多行的字符串。
import (
"fmt"
)
func main() {
var mystr01 string = `你好呀!
我的公眾號是: Go編程時光,歡迎大家關注`
fmt.Println(mystr01)
}
輸出如下
你好呀!
我的公眾號是: Go編程時光,歡迎大家關注
系列導讀
24. 超詳細解讀 Go Modules 前世今生及入門使用
本文由博客一文多發平台 OpenWrite 發布!