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 站!

相关文章
相关标签/搜索