Go 語言 for 循環與 string

問題

昨天寫代碼時,發現了一個我之前沒有注意到的 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 對於[]bytestringrune的設計。這讓字符處理變得很容易了。做爲曾經的一個 Python2 程序員,個人吐槽仍是到位的。htm

space.bilibili.com/16696495

歡迎你們關注個人公衆號以及 B 站!

相關文章
相關標籤/搜索