最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go語言中的UTF-8實現(xiàn)

 更新時間:2021年04月26日 11:48:54   作者:Rayjun  
這篇文章主要介紹了Go語言中的UTF-8實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

計算機剛誕生的時候,計算機內(nèi)的字符可以全部由 ASCII 來表示,ASCII 字符的長度是 7 位,可以表示 128 個字符,對于美國等國家來說是夠了,但是對于世界上的其他國家,特別是東亞國家,文字不是由字母組成,漢字就有幾萬個,ASCII 碼根本不夠用。

字符本質(zhì)就是對應計算機中的一個數(shù)值,既然不夠用,那么解決方法就是把這個范圍擴大,Unicode 的出現(xiàn)就解決了這個問題,它包括了世界上所有的字符,每一個字符都對應一個數(shù)值,這個數(shù)值被稱之為 Unicode 碼點。

但是 Unicode 也不是沒有缺點,因為表示的范圍大,所以每一個 Unicode 都需要 4 個字節(jié)來表示,但是對于原本的 ASCII 編碼,本來只需要一個字節(jié),現(xiàn)在也需要 4個字節(jié),這樣會浪費很多存儲。

UTF-8 的出現(xiàn)解決了這個問題,它解決問題的思路是讓每個字符選擇自己的大小,需要多少字節(jié)就用多少。對于占不同字節(jié)的字符,有不同的表示格式:

  • 1 字節(jié):0xxxxxxx
  • 2 字節(jié):110xxxxx 10xxxxxx
  • 3 字節(jié):1110xxxx 10xxxxxx 10xxxxxx
  • 4 字節(jié):11110xxx 10 xxxxxx 10xxxxxx 10xxxxxx

通過識別每個字符串的頭部來判斷占幾個字節(jié)。

每個 Unicode 字符都對應一個碼點,在字符串中,可以對碼點進行轉(zhuǎn)義,使用 \uhhhh 表示 16 位碼點,使用 \Uhhhhhhhh 來表示 32 位碼點,每一個 h 都代表一個十六進制的數(shù)字。

這里有一點比較特殊,對于碼點值小于 256 的文字符號可以使用單個十六進制的數(shù)字來表示,比如 'A' 可以使用 '\x41' 來表示,對于大于 256 的碼點,就必須使用 \u 或者 \U 來轉(zhuǎn)義。

Go 語言對于 UTF-8 的支持很好,這里有一點很有意思,Go 語言的兩位作者 Ken Thompson 和 Rob Pike 同時也是 UTF-8 的發(fā)明者,Go 語言對 UTF-8 的支持贏在起跑線。

Go 語言總是使用 UTF-8 來處理源文件,同時也是優(yōu)先使用 UTF-8 來處理字符串。所以上面說到的那些 Unicode 字符的轉(zhuǎn)義被 Go 直接處理,比如下面三個字符串在 Go 語言中是等價的:

"世界"
"\u4e16\u754c"
"\U00004e16\U0000u754c"

Go 字符串使用只讀的 []byte 來存儲,所以字符串值是不變的,這樣做更安全,效率也很高:

s := "left root"
t := s
s += ", right root"

fmt.Println(s) // left root, right root
fmt.Println(t) // left root

在上面的例子中, s 的值出現(xiàn)了變化,但是 t 的值還是舊的字符串。由于是 [] byte 是 slice 類型,所以字符串的截取操作效率很高,但是在字符串截取的過程中,就會出現(xiàn)一些坑。
Go 中的字符串底層使用了只讀的 []byte 來存儲,所以**本質(zhì)上 Go 語言中的字符串是使用字節(jié)來表示,而不是字符表示,**理解這一點很重要。

str := "hello world"
fmt.Println(str[:2]) // he

str = "你好,世界"
fmt.Println(str[:2]) // ��,這個符號用來表示 UTF-8 里面的未知字符,碼點是

非 ASCII 碼的字符一般占用的字節(jié)會超過一個,如果直接截取,就會導致截取不到正確的位置,從而亂碼。在上面的例子中,一個中文字符占 3 個字節(jié),只有嚴格按照字節(jié)數(shù)來截取才能獲取到顯示正常的字符:

str = "你好,世界"
fmt.Println(str[:3]) // 你

那么在這個時候,如果要按照字符截取,就需要把字符串轉(zhuǎn)成 []rune,每個 rune 都代表一個 UTF-8 中的碼點,對 []rune 按照字符截取就不會出現(xiàn)亂碼:

str = "你好,世界"
runeStr := []rune(str)
fmt.Println(string(runeStr[:1])) // 你

把字符串轉(zhuǎn)成 []rune,就是把字符串轉(zhuǎn)成 UTF-8 碼點,而不是 []byte,rune 其實就是 int32 類型。

Go 語言中有一個專門 unicode/utf8 包來處理 utf8 字符。由于每個字符占據(jù)的字節(jié)可能不一樣,所以字符數(shù)和字節(jié)數(shù)大小是兩回事:

s := "Hello, 世界" // 逗號是半角符號
fmt.Println(len(s))                    // 13
fmt.Println(utf8.RuneCountInString(s)) // 9

如果要獲取字符占據(jù)的總字節(jié)數(shù),就使用 len 方法,如果需要計算字符的個數(shù),那就需要使用 utf8.RuneCountInString 方法。
這個包里面還提供了其他常用函數(shù):

// 判斷是否符合 utf8 編碼:
func Valid(p []byte) bool
func ValidRune(r rune) bool
func ValidString(s string) bool
// 判斷 rune 所占的字節(jié)數(shù)
func RuneLen(r rune) int
// 判斷字節(jié)串或者字符串中的 rune 字符數(shù)
func RuneCount(p []byte) int
func RuneCountInString(s string) int
// 對 rune 的編碼和解碼
func EncodeRune(p []byte, r rune) int
func DecodeRune(p []byte) (r rune, size int)
func DecodeRuneInString(s string) (r rune, size int)
func DecodeLastRune(p []byte) (r rune, size int)
func DecodeLastRuneInString(s string) (r rune, size int)

除了 utf8 包之外, unicode 包對提供了一系列 IsXX 函數(shù)來 rune 的檢查:

func Is(rangeTab *RangeTable, r rune) bool // 是否是 RangeTable 類型的
func In(r rune, ranges ...*RangeTable) bool  // 是否是 ranges 中任意一個類型的字符
func IsControl(r rune) bool  // 是否是控制字符
func IsDigit(r rune) bool  // 是否是阿拉伯數(shù)字字符,即 0-9
func IsGraphic(r rune) bool // 是否是圖形字符
func IsLetter(r rune) bool // 是否是字母
func IsLower(r rune) bool // 是否是小寫字符
func IsMark(r rune) bool // 是否是符號字符
func IsNumber(r rune) bool // 是否是數(shù)字字符,包含羅馬數(shù)字
func IsOneOf(ranges []*RangeTable, r rune) bool // 是否是 RangeTable 中的一個
func IsPrint(r rune) bool // 是否是可打印字符
func IsPunct(r rune) bool // 是否是標點符號
func IsSpace(r rune) bool // 是否是空格
func IsSymbol(r rune) bool // 是否符號字符
func IsTitle(r rune) bool // 字符串中的每個單詞的第一個字符是否是大寫
func IsUpper(r rune) bool // 是否是大寫字符

RangeTable 是對所有 Unicode 字符的分類,比如驗證一個字符是否是漢字:

r := '中'
result := unicode.Is(unicode.Han, r)
fmt.Println(result) // true

其中 unicode.Han 就是 RangeTable 類型,表示漢字。

到此這篇關于Go語言中的UTF-8實現(xiàn)的文章就介紹到這了,更多相關Go語言UTF-8內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • go語言中os包的用法實戰(zhàn)大全

    go語言中os包的用法實戰(zhàn)大全

    Go在os中提供了文件的基本操作,包括通常意義的打開、創(chuàng)建、讀寫等操作,除此以外為了追求便捷以及性能上,Go還在io/ioutil以及bufio提供一些其他函數(shù)供開發(fā)者使用,這篇文章主要給大家介紹了關于go語言中os包用法的相關資料,需要的朋友可以參考下
    2024-02-02
  • golang中select語句的簡單實例

    golang中select語句的簡單實例

    Go的select語句是一種僅能用于channl發(fā)送和接收消息的專用語句,此語句運行期間是阻塞的,下面這篇文章主要給大家介紹了關于golang中select語句的相關資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-06-06
  • Go語言HTTPServer開發(fā)的六種方式小結(jié)

    Go語言HTTPServer開發(fā)的六種方式小結(jié)

    Golang的Server開發(fā)顯得非常簡單,有很多種方式,本文就介紹了Go語言HTTPServer開發(fā)的六種方式,具有一定的參考價值,感興趣的可以了解一下
    2021-11-11
  • Go?復合類型之字典類型使用教程示例

    Go?復合類型之字典類型使用教程示例

    這篇文章主要為大家介紹了Go復合類型之字典類型使用教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • 詳解golang 模板(template)的常用基本語法

    詳解golang 模板(template)的常用基本語法

    這篇文章主要介紹了詳解golang 模板(template)的常用基本語法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Go語言列表List獲取元素的4種方式

    Go語言列表List獲取元素的4種方式

    Golang的列表元素的獲取可以使用內(nèi)置的 Front 函數(shù)獲取頭結(jié)點,使用 Back 函數(shù)獲取尾結(jié)點,使用 Prev 獲取前一個結(jié)點,使用 Next 獲取下一個結(jié)點,本文就介紹了Go語言列表List獲取元素的4種方式,感興趣的可以了解一下
    2022-04-04
  • Golang中int,?int8,?int16,?int32,?int64和uint區(qū)別淺析

    Golang中int,?int8,?int16,?int32,?int64和uint區(qū)別淺析

    go語言中的int的大小是和操作系統(tǒng)位數(shù)相關的,如果是32位操作系統(tǒng),int類型的大小就是4字節(jié),如果是64位操作系統(tǒng),int類型的大小就是8個字節(jié),下面這篇文章主要給大家介紹了關于Golang中int,?int8,?int16,?int32,?int64和uint區(qū)別的相關資料,需要的朋友可以參考下
    2022-11-11
  • golang中context的作用詳解

    golang中context的作用詳解

    這篇文章主要介紹了golang中context的作用,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • GO語言中通道和sync包的使用教程分享

    GO語言中通道和sync包的使用教程分享

    這篇文章主要為大家詳細介紹了Go語言中通道和sync包的相關資料,文中的示例代碼講解詳細,對我們學習Go語言有一定的幫助,需要的可以參考一下
    2023-02-02
  • Go語言WaitGroup使用時需要注意的坑

    Go語言WaitGroup使用時需要注意的坑

    Go語言中WaitGroup的用途是它能夠一直等到所有的goroutine執(zhí)行完成,并且阻塞主線程的執(zhí)行,直到所有的goroutine執(zhí)行完成。之前一直使用也沒有問題,但最近通過同事的一段代碼引起了關于WaitGroup的注意,下面這篇文章就介紹了WaitGroup使用時需要注意的坑及填坑。
    2016-12-12

最新評論

延安市| 马关县| 黑山县| 伊春市| 满洲里市| 六盘水市| 南岸区| 土默特左旗| 任丘市| 德惠市| 景宁| 镇康县| 洪湖市| 白城市| 都兰县| 清新县| 平和县| 洛浦县| 宿州市| 东山县| 腾冲县| 肥东县| 平昌县| 临猗县| 蕲春县| 泽库县| 大安市| 封开县| 卢龙县| 分宜县| 沙田区| 江津市| 青海省| 北海市| 广昌县| 德庆县| 砚山县| 财经| 肇东市| 连南| 大同县|