成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Golang 中的 Unicode 與 UTF-8

開發 前端
我們知道,在計算機內部,為了把二進制數據轉換為顯示器上,需要進行編碼,即將可顯示的字符一一對應到二進制數據上,比如 ASCII 碼,就是用一個 Byte 的數據來表示英文字符加上一些英文符號。

大多數的我們,真正認識到有字符編碼這回事,一般都是因為遇到了亂碼,因為我國常用的編碼是 GBK 以及 GB2312:用兩個 Byte 來表示所有的漢字,這樣,我們一共可以表示 2^16 = 65536 個字符,一旦我們的 GBK 以及 GB2312 編碼遇到了其他編碼,比如日本,韓國的編碼,就會變成亂碼,當然,這時候如果是 UTF-8,也會亂碼。

我們知道,在計算機內部,為了把二進制數據轉換為顯示器上,需要進行編碼,即將可顯示的字符一一對應到二進制數據上,比如 ASCII 碼,就是用一個 Byte 的數據來表示英文字符加上一些英文符號。

至于中文,我們顯然不能使用僅僅一個 Byte 來表示,我們需要用到更大的空間。

Unicode 與 Code point

在如今這個小小的世界村里,有著那么多的語言與文字,為了兼容所有的字符,Unicode 出現了,但是它需要有更多的 Byte 來將這個世界上所有的字符收納進去(這里面甚至包含了 Emoji )。

為了了解 Unicode,你需要了解 Code point 即所謂的碼點,也就是用 4 個 Byte 大小的數字來表示所有的字符。

至于 Unicode 本身,你可以認為它就是 Code point 的集合,而 UTF-8 呢?就是 Unicode 的編碼方式。

Unicode 與 UTF-8 編碼

下面的圖來自 UTF-8 的截圖:

 

Golang 中的 Unicode 與 UTF-8

這幅圖簡單明了的告訴我們,UTF-8 的編碼方式,比如漢字一般用三個 Byte,每個 Byte 的開頭都是固定的,各種文字軟件解析 UTF-8 編碼的時候,它就會按照這個格式去解析,一旦解析錯誤(畢竟還可能會有不符合要求的數據,或者是文件錯誤了),錯誤的字節就會被替換為 “�” (U+FFFD),然后神奇的地方就來了: 即使遇到這種錯誤,它也不會影響接下來的其他字符的解析 ,因為這種編碼不必從頭開始,使得它可以 自我同步(Self-synchronizing) 。與此同時,其它的一些編碼一旦遇到錯誤編碼就會出問題,導致錯誤編碼之后的正確編碼也會跟著出錯。

當然,UTF-8 編碼也有缺點,由于它是可變的,當英文字符偏多的時候,它會省空間,然而比如當中文偏多的時候,它理論上(3 Byte)會比 GBK 編碼(2 Byte)最多多出 1/3 的存儲空間。

UTF-8 的例子

我們拿 Unicode 中最受歡迎的 Emoji 表情 :joy: 1 來舉例:它的 Code point 是 U+1F602 (對, 1F602 是以 16 進制表示的),然而在內存中它的存儲方式的卻是 0xf09f9882 ,為什么?這就是 UTF-8 的編碼了(注意對比上圖的編碼方式):

  1. 000    011111    011000    000010 1f602 
  2. 11110000  10011111  10011000  10000010 f0 9f 98 82 

通過把 UTF-8 的編碼格子里面數據提取出來,我們就能獲得 Code point 1F602 。

你也可以用 Golang 來查看其它字符的編碼:

  1. package main 
  2. import (    "fmt" 
  3.     "unicode/utf8" 
  4. )func main() { 
  5.     fmt.Printf("%b\n", []byte(`:joy:`)) 
  6.     fmt.Printf("% x\n", []byte(`:joy:`)) 
  7.         r, _ := utf8.DecodeRuneInString(`:joy:`) 
  8.     fmt.Printf("% b\n", r) 
  9.     fmt.Printf("% x\n", r) 

Unicode 的其他編碼

Unicode 當然不止一種編碼,還有 UTF-16、UTF-32 等,它們的關系就是 UTF-16 用 2 個 Byte 來表示 UTF-8 分別用 1/2/3 個 Byte 來表示的字符,然后 4 個 Byte 與 UTF-8 一致,UTF-32 是完全用 4 個 Byte 來表示所有的字符,另外,詳細的可以在 Comparison of Unicode encodings 中看到,

好,基礎講完,現在開始正式介紹。

Unicode 與 Golang 2

這里特別需要提到的是 Golang 與 UTF-8 的關系,他們背后的男人,都是 Ken Thompson 跟 Rob Pike 3 4 5 ,由此,大家就會明白 Golang 的 UTF-8 設計是有多么重要的參考意義。比如 Golang 設計了一個 rune 類型來取代 Code point 的意義。

rune 看源碼就知道,它就是 int32,剛好 4 個 Byte,剛可以用來表示 Unicode 的所有編碼 UTF-8 與 UTF-16。

在繼續之前,我想幫各位明白一個事實:Golang 的源碼是默認 UTF-8 編碼的,這點從上面我給出的例子中就能明白,所以表情字符在編譯的時候,就已經能被解析。

好了,那么我們來看看 Golang 的 unicode 包,其中就會有很多有用的判斷函數:

  1. func IsControl(r rune) bool 
  2. func IsDigit(r rune) bool 
  3. func IsGraphic(r rune) bool 
  4. func IsLetter(r rune) bool 
  5. func IsLower(r rune) bool 
  6. func IsMark(r rune) bool 
  7. func IsNumber(r rune) bool 
  8. func IsPrint(r rune) bool 
  9. func IsPunct(r rune) bool 
  10. func IsSpace(r rune) bool 
  11. func IsSymbol(r rune) bool 
  12. func IsTitle(r rune) bool 
  13. func IsUpper(r rune) bool 

另外,在 src/unicode/tables.go 中,有大量的 Unicode 中,各類字符的 Code point 區間,會有比較大的參考價值。

再看看 unicode/utf8 包,這里面的函數,大多數時候你都用不到,但是有這么幾類情況就需要你必須得用到了:

  • 統計字符數量;
  • 轉編碼,比如將 GBK 轉為 UTF-8;
  • 判斷字符串是否是 UTF-8 編碼,或者是否含有不符合 UTF-8 編碼的字符;

后面兩個可以忽略,第一個需要特地提醒下:

  1. s := `:joy:` 
  2. fmt.Println(len(s)) 

這句輸出是什么?上面提過了,剛好就是 4。于是,你不能使用 len 來獲取字符數量,也就不能以此來判斷用戶輸入的字符是不是超過了系統的限制。另外,你也不能通過 s[0] 這樣的方式來獲取字符,因為這樣你只能取到這 4 個 Byte 中的第一個,也就是 0xf0 。

你應該做的就是把 string 轉為 rune 數組,然后再去進行字符的操作。

具體的使用方法就不細談了,相信你們能搞定。

另外,這里需要另外提示下,在 Node.js 中,string 本身就是 Unicode,而不是像 Golang 的 string 是二進制,因此在這里可以認為 Node.js 的 Buffer 才是 Golang 中的 string。

好了,最后留給你一個思考題:在 Node.js 中,為什么在處理 Buffer 時候,不能直接拼接?

責任編輯:未麗燕 來源: 今日頭條
相關推薦

2021-05-12 07:43:02

LinuxUnicodeUTF-8

2024-05-29 13:05:44

2023-12-08 08:18:41

代號UnicodeUTF-8

2016-12-13 10:13:18

PHPUTF-8實踐

2010-09-29 11:29:18

UnicodeJ2ME

2023-01-26 00:31:25

ASCIIBase64UTF-8

2011-08-25 09:43:51

UTF-8中文man

2024-01-04 12:53:00

Unicode字符UTF-8

2011-03-07 12:31:54

Filezilla

2009-12-17 11:45:38

Linux UTF-8

2024-02-20 13:12:00

UnicodeUTF-8GB2312

2009-12-16 09:45:13

UbuntuUbuntu ServUTF-8

2019-04-15 14:05:56

MySQLUTF-8數據庫

2020-09-22 09:05:45

MySQLUTF-8utf8mb4

2011-07-29 14:08:26

iPhone UTF-8 XML

2016-11-15 14:29:14

Linux文件編碼轉換

2010-01-08 11:52:37

ibmdwDB2

2010-03-05 17:06:26

Python顯示UTF

2009-11-30 10:40:46

PHP截取utf-8字

2009-10-29 12:27:54

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人精品视频99在线观看免费 | 国产精品久久久久久久久久久久 | 国产精品国产三级国产a | 国产黄色大片在线免费观看 | 精精国产xxxx视频在线播放 | 久久久久综合 | 国产精品亚洲一区二区三区在线 | 九九国产| 国产欧美一区二区精品久导航 | 91精品国产91久久久久久吃药 | 亚州一区二区三区 | 午夜精品久久久久99蜜 | 欧美日韩精品一区二区三区四区 | 国产三级国产精品 | 国产一区二区三区久久久久久久久 | 亚洲精品在线观看网站 | 欧美一区二区三区的 | 中文字幕第90页 | 成人在线h| 欧美小视频在线观看 | 成人影院免费视频 | 成人在线观看亚洲 | 亚洲国产精品一区在线观看 | 狠狠干美女 | 亚洲视频在线免费观看 | 午夜欧美一区二区三区在线播放 | 一级片在线播放 | 欧美性生活一区二区三区 | 日韩精品在线一区 | 成人免费视频在线观看 | 午夜性视频 | 91天堂| 麻豆av在线免费观看 | 日韩欧美在线观看视频 | 欧美成人视屏 | 成人综合视频在线观看 | 欧美www在线| 99热精品久久 | 一区欧美 | 午夜三级在线观看 | 亚洲欧美一区二区三区情侣bbw |