昨天寫代碼時,發現了一個我之前沒有注意到的 Go 語言特性。html
請看下面這一段代碼程序員
import "strings"
func someFunc() {
s := "some words"
for i, c := range s {
strings.Contains("another string", c)
}
}
複製代碼
這段代碼實際上是過不了編譯的。由於Contains
的簽名爲func Contains(s, substr string) bool
,而c
的類型已經變成rune
了。golang
rune
在英語裏是符文的意思,玩魔幻RPG遊戲的朋友應該很清楚。在 Go 裏,一個rune
表示一個 Unicode code point。而 Go 的 for 循環會自動將 string 看成 unicode 來解析,返回的i
是字節位,c
是單個 unicode 字符。bash
好比下面這段代碼(引用自官方文檔:golang.org/doc/effecti… )函數
for pos, char := range "日本\x80語" { // \x80 is an illegal UTF-8 encoding
fmt.Printf("character %#U starts at byte position %d\n", char, pos)
}
複製代碼
會打印spa
character U+65E5 '日' starts at byte position 0
character U+672C '本' starts at byte position 3
character U+FFFD '�' starts at byte position 6
character U+8A9E '語' starts at byte position 7
複製代碼
因此說,個人代碼有兩種改進方法。設計
import "strings"
func someFunc() {
s := "some words"
for i, c := range s {
strings.Contains("another string", string(c))
}
}
複製代碼
將c
強轉回 string。code
import "strings"
func someFunc() {
s := "some words"
for i, c := range s {
strings.ContainsRune("another string", c)
}
}
複製代碼
使用ContainsRune
函數。cdn
其實在對付 unicode 這個問題上,在非英語國家工做的程序員會更有經驗。我本人不多和其打交道。不過,我很喜歡 Go 對於[]byte
、string
、rune
的設計。這讓字符處理變得很容易了。做爲曾經的一個 Python2 程序員,個人吐槽仍是到位的。htm
歡迎你們關注個人公衆號以及 B 站!