Go 语言 for 循环与 string

问题

昨天写代码时,发现了一个我以前没有注意到的 Go 语言特性。

请看下面这一段代码

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了。


原因

rune在英语里是符文的意思,玩魔幻RPG游戏的朋友应该很清楚。在 Go 里,一个rune表示一个 Unicode code point。而 Go 的 for 循环会自动将 string 当作 unicode 来解析,返回的i是字节位,c是单个 unicode 字符。

比如下面这段代码(引用自官方文档: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)
}
复制代码

会打印

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。

方法二

import "strings"

func someFunc() {
    s := "some words"
    for i, c := range s {
        strings.ContainsRune("another string", c)   
    }
}
复制代码

使用ContainsRune函数。


结语

其实在对付 unicode 这个问题上,在非英语国家工作的程序员会更有经验。我本人很少和其打交道。不过,我很喜欢 Go 对于[]bytestringrune的设计。这让字符处理变得很容易了。作为曾经的一个 Python2 程序员,我的吐槽还是到位的。

space.bilibili.com/16696495

欢迎大家关注我的公众号以及 B 站!

转载于:https://juejin.im/post/5c9c11a96fb9a070c6189a1b

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值