昨天写代码时,发现了一个我之前没有注意到的 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 站!