Go1.18 新特性:新增好用的 Cut 方法
大家好,我是煎鱼。
在各种写业务代码的时候,大家会常常要处理字符串的内容。常见的像是用邮箱登陆账号,如果是:[email protected],那就得根据 @ 来切割,分别取出前和后,来识别用户名和邮箱地址。
这种需求,在 Go 里写起来方便吗?今天就由煎鱼带大家了解。
背景
重复代码
无独有偶,Ainar Garipov 在许多项目中遇到了前面我们所提的切割需求。
例如:
idx = strings.Index(username, "@")
if idx != -1 {
name = username[:idx]
} else {
name = username
}
又或是:
idx = strings.LastIndex(address, "@")
if idx != -1 {
host = address[idx+1:]
} else {
host = address
}
经常要反复写一些繁琐的代码,提案提出者表示不愉快。
新提案
实施内容
建议新增 Cut 方法到 strings 标准库:
func Cut(s, sep string) (before, after string, found bool) {
if i := Index(s, sep); i >= 0 {
return s[:i], s[i+len(sep):], true
}
return s, "", false
}
同步也要在 bytes 标准库:
func Cut(s, sep []byte) (before, after []byte, found bool)
这样一来,就可以从原本的:
eq := strings.IndexByte(rec, '=')
if eq == -1 {
return "", "", s, ErrHeader
}
k, v = rec[:eq], rec[eq+1:]
变成:
k, v, ok = strings.Cut(rec, "=")
if !ok {
return "", "", s, ErrHeader
}
写法上会更优雅,在复杂的场景下会更具可读性和抽象级别。
接受原因
可能就有小伙伴会吐槽了,Go 居然只为了节省 1 行代码,就搞了个新函数,这还是大道至简吗?
实际上,在官方团队(Russ Cox)介入后,他对 Go 主仓库进行了分析,搜索了相关类似函数的使用:
-
strings.Index。
-
strings.IndexByte。
-
strings.IndexRune。
统计后,转换为了可以使用 strings.Cut
的用法,在例子和测试数据之外有 311 个索引调用。
排除了一些确实不需要的,剩下 285 个调用。在这些调用中,有 221 次是最好写成 Cut 方法的,能更优雅。

也就是说,有现有的 Go 代码中,有 77% 可以用新增的 Cut 函数写得更清楚,可读性和抽象可以做得更好。
Go 主仓库确实存在如此重复的代码,他认为这也是非常不可思议的!
总结
Go1.18 的新特性中,Cut 虽然只是新增了一个方法,看上去无伤大雅。
但类似 Cut 方法的用法,在 Go 的主版本中其实已经被发明了两次。
该新方法的出现,可以同时取代并简化四个不同的标准库函数:Index、IndexByte、IndexRune 和 SplitN 中的绝大部分用法。
由于这些原因,最终将 Cut 添加到标准库中。
你觉得怎么样?:)
参考
-
bytes, strings: add Cut
关注煎鱼,获取业内第一手消息和知识 :point_down:
你好,我是煎鱼, 出版过 Go 畅销书《Go 语言编程之旅》,再到获得 GOP(Go 领域最有观点专家)荣誉, 点击蓝字查看我的出书之路 。
日常分享高质量文章,输出 Go 面试、工作经验、架构设计, 加微信拉读者交流群,和大家交流!
- Go 错误处理中再套个娃,能解决烦恼不?
- 10 条 Go 官方谚语,你知道几条?
- 新提案:创建 Go 简单类型的指针表达式
- 为什么 Go 语言能在中国这么火?
- 好物分享:快速找到 Goroutine 泄露的地方
- 新提案:增加标准库 Context 的取消 API
- Go 之父:聊聊我眼中的 Go 语言和环境
- 太疯狂了,Go 程序说 nil 不是 nil...
- Go 返回值命名还有存在的必要吗?
- Go 要违背初心吗?新提案:手动管理内存
- 开启 Go 泛型时代:第三方泛型库分享
- 你能答对这道 Go 题目吗?超过 80% 的人都答错了...
- 网友:Go 你是 Google 的,Go:我不是。
- Go1.18 新特性:高效复制,strings, bytes 标准库新增 Clone API
- 我敢说,它严重被低估了
- Go1.18 新特性:新增好用的 Cut 方法
- Go1.18 新特性:编译后的二进制文件,将包含更多信息
- 分享 2 个 Go1.18 新特性的官方教程
- Postman的霸主地位被动摇了!
- 为什么要开发 Go 这门新语言?