Go 的 rune byte 和 string

  • runebytestring 都是 Go 的內置類型

  • byte
    • byte是uint8的別名,在所有方面都等同於uint8
    • 按慣例,它用於區分字節值8位無符號整數值
  • rune
    • runeint32的別名,在所有方面都等同於int32
    • 按慣例,它用於區分字符值整數值
  • string
    • string是所有8位字節字符串的集合,通常但不一定代表UTF-8編碼的文本
    • 字符串可能爲空,但是不能爲 nil
    • 字符串類型的值是不可變的
  • 由上面得解釋我們大概可以明白
    • rune 可以表示得比 byte
    • string 類型的底層是一個byte 數組
    • 以上解釋都來此 Go 源碼註釋

  • 剛剛上面標註了字節字符,現在我們來梳理字符和字節的概念

  • 存儲單位 字節

    • 計算機存儲信息的最小單位,稱之爲 bit,二進制的一個01叫一位
    • 計算機存儲容量基本單位是字節 Byte,8個二進制位組成 1 個字節
  • 信息表示單位 字符

    • 字符 是一種符號,像 英文a和中文 就是不同字符
    • 不同的字符在不同的編碼格式下,所需要的存儲單位不一樣
      • ASCLII 編碼中一個英文字母一字節,一個漢字兩字節
      • UTF-8 編碼中 一個英文字母一字節,一個常見漢字3字節,不常用的超大字符集漢字4字節

  • Go 源碼文件默認採用Unicode字符集,Unicode碼點和內存中字節序列的變換實現使用了UTF-8,這使得Go編程無需考慮編碼轉換的問題非常方便
  • 從編碼上來分析
    • byte用來強調一個字節代表的數據(例如字符 a 就是 97),而不是數字;
    • rune用來表示Unicode的碼點,即一個字符
  • 通俗一點
    • byte 只能操作簡單的字符,不支持中文操作
    • rune 能操作任何字符

  • 代碼演示
package main

import (
	"fmt"
	"unicode/utf8"
)

func main() {

	str := "hello 世界!"
	fmt.Println(str)              
	fmt.Println(len(str))
	fmt.Println(utf8.RuneCountInString(str))
	fmt.Println(str[1])
	fmt.Println(string(str[1]))
	fmt.Println(str[1:])
	fmt.Println(str[7:])

}

*************************************
輸出
hello 世界!
13
9
101
e
ello 世界!
��界!
  • 會輸出 hello 世界!,這證明 GoUTF-8 編碼的,輸出長度爲 13 這說明了一個漢字3字節
  • 輸出 ello 世界! 說明 string 底層的數據結構是數組
  • 輸出 ��界! 說明 string 底層是一個byte 數組,不然不會亂碼

package main

import "fmt"

func StrChangeByRune(str *string, i int, ch rune) {

	temp := []rune(*str)
	temp[i] = ch
	*str = string(temp)
}

func StrChangeByByte(str *string, i int, ch byte) {

	temp := []byte(*str)
	temp[i] = ch
	*str = string(temp)
}

func main() {

	str := "你好 hello"
	str1 := "你好 hello"
	StrChangeByRune(&str, 1, 'A')
	StrChangeByByte(&str1, 1, 'A')
	fmt.Println(str)
	fmt.Println(str1)

}


*******************************
輸出
你A hello
�A�好 hello
  • 由輸出 你A hello�A�好 hello 可以看出
  • byte 的操作單位是一個字節,可以理解爲一個英文字符
  • rune 的操作單位是一個字符,不管這個字符是什麼字符
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章