在 Go 語言中處理 Unicode

2021-09-08 16:42:38 字數 2886 閱讀 6100

如果『go』通常是指在公園散步,用go語言處理unicode碼可以描述為不小心走進了雷區,比如,如果我們要獲取從前端頁面的一句簡單字串「hello,世界」的長度.會得到什麼結果?

1fmt.println(len("hello, 世界"))

2>>> 13

等下,剛才發生了什麼?長度難道不該是9麼?其他額外的4個字元是從哪來的?在編譯中,go 實際上把字串編碼為乙個byte.go不像python2.x一樣讓你區分普通ascii碼並反編碼處理字串,所以go還是不能從將中文字元編碼為 byte的實現中抽離出來,因為中文字元在ascii表示中占用3byte而普通字元只占用1byte,所以go告訴你長度是 1*7+3*2=13.這對於那些想測試他們的ascii字串長度的人將是個令人迷惑的大水坑!看下面的例子

1hello :="hello, 世界"fori := range hello

4>>> hello, äç

出問題了,好吧,『世界』怎麼變成了『

äç』?也許我已經能聽到你的咆哮了。。但是當你使用第二種range處理字串,你確實可以這樣處理

1hello :="hello, 世界"for_, c := range hello

4>>> hello, 世界

bigowen

翻譯於 昨天(10:25)

0人頂 頂 翻譯的不錯哦!

結果好了很多! 但我們確實不能這樣做,為什麼? 用乙個小例子, 假設我們只是想用字串中的每個字元與下個字元比較是否一樣的. 簡單的處理方式可能是這樣:

1func comparechars(word string)

4}

5}

6...

7comparechars("hello")

8>>>false,false,true,false,

可是使用ascii的字串作為入參,結果實在是太爛了!如果我們使用中文說你好的話情況會是這樣:

1comparechars("你好好好")

2>>>false,false,false,false,

很明顯這些字串永遠不會相等,因為我們總是用『好』和好的第一byte的ascii碼『\xe5』比較。

那麼該怎麼辦?如果我們探索的夠深,就會發現go排除了unicode/utf8的引用包,這個包不提供特別多功能,但是卻能是我們解決遇到的第乙個問題,查詢『hello』字串的長度:

1import ("fmt""unicode/utf8") ... fmt.println(utf8.runecountinstring("hello, 世界"))

2>>> 9

bigowen

翻譯於 昨天(11:17)

0人頂 頂 翻譯的不錯哦!

好了,我們一開始期望的長度出現了。現在來公升級一下我們先用到的comparechars 函式,使它能比較unicode編碼。

1func comparechars(word string) }

2... comparechars("hello")

3>>>false,false,true,false, comparechars("你好好好")

4>>>false,true,true,

起作用了!

這個故事的寓意:工作時要非常小心,尤其是當與迴圈中的unicode遍歷字串。最重要的是,在適當的情況下,使用內建的utf-8封裝,並牢記寫測試要包含unicode和ascii字串,。

GO語言中的異常處理

go語言內建了乙個簡單的錯誤介面作為一種錯誤處理機制,介面定義如下 type error inte ce 它包含乙個 error 方法,返回值為string go的error構造有兩種方式,分別是 第一種 errors.new err errors.new this is an error if e...

在Go語言中使用JSON

將乙個物件編碼成json資料,接受乙個inte ce 物件,返回byte和error func marshal v inte ce byte,error marshal函式將會遞迴遍歷整個物件,依次按成員型別對這個物件進行編碼,型別轉換規則如下 bool型別轉換為json的boolean 整數,浮點...

在Go語言中使用氣泡排序?

氣泡排序實現 go語言中陣列的定義 1.用var關鍵字定義,var arr 5 int,需要指定元素個數 2.用 定義,arr 3 int,需要賦初值 用 定義,由編譯器計算元素個數,arr int 氣泡排序 第1個元素和第2個元素比較,若a j a j 1 那麼交換位置 0.思想 n個元素,依次處...