Go1.18 快讯:新增的 Cut 函数太方便了

发布于 2021-11-18 17:05 ,所属分类:软件编程学习资料

阅读本文大概需要 6 分钟。

大家好,我是 polarisxu。

在编程中,字符串使用是最频繁的。Go 语言对字符串相关的操作也提供了大量的 API,一方面,字符串可以向普通 slice 一样进行相关操作;另一方面,标准库专门提供了一个包 strings 进行字符串的操作。

01 strings.Index 系列函数

假如有一个这样的需求:从 192.168.1.1:8080 中获取 ip 和 port。

我们一般会这么实现:

addr:="192.168.1.1:8080"
pos:=strings.Index(addr,":")
ifpos==-1{
panic("非法地址")
}
ip,port:=addr[:pos],addr[pos+1:]

实际项目中,pos == -1 时应该返回 error

此处忽略通过 net.TCPAddr 方式得到,主要在于讲解字符串处理。

strings 包中,Index 相关函数有好几个:

funcIndex(s,substrstring)int
funcIndexAny(s,charsstring)int
funcIndexByte(sstring,cbyte)int
funcIndexFunc(sstring,ffunc(rune)bool)int
funcIndexRune(sstring,rrune)int
funcLastIndex(s,substrstring)int
funcLastIndexAny(s,charsstring)int
funcLastIndexByte(sstring,cbyte)int
funcLastIndexFunc(sstring,ffunc(rune)bool)int

Go 官方统计了 Go 源码中使用相关函数的代码:

  • 311 Index calls outside examples and testdata.
  • 20 should have been Contains
  • 2 should have been 1 call to IndexAny
  • 2 should have been 1 call to ContainsAny
  • 1 should have been TrimPrefix
  • 1 should have been HasSuffix

相关需求是这么多,而 Index 显然不是处理类似需求最好的方式。于是 Russ Cox 提议,在 strings 包中新增一个函数 Cut,专门处理类似的常见。

02 新增的 Cut 函数

Cut 函数的签名如下:

funcCut(s,sepstring)(before,afterstring,foundbool)

将字符串 s 在第一个 sep 处切割为两部分,分别存在 before 和 after 中。如果 s 中没有 sep,返回 s,"",false

根据 Russ Cox 的统计,Go 源码中 221 处使用 Cut 会更好。

针对上文提到的需求,改用 Cut 函数:

addr:="192.168.1.1:8080"
ip,port,ok:=strings.Cut(addr,":")

是不是很清晰?!

这是又一个改善生活质量的优化。

针对该函数,官方提供了如下示例:

packagemain

import(
"fmt"
"strings"
)

funcmain(){
show:=func(s,sepstring){
before,after,found:=strings.Cut(s,sep)
fmt.Printf("Cut(%q,%q)=%q,%q,%v\n",s,sep,before,after,found)
}
show("Gopher","Go")
show("Gopher","ph")
show("Gopher","er")
show("Gopher","Badger")
}

//Output:
/*
Cut("Gopher","Go")="","pher",true
Cut("Gopher","ph")="Go","er",true
Cut("Gopher","er")="Goph","",true
Cut("Gopher","Badger")="Gopher","",false
*/

03 总结

从 PHP 转到 Go 的朋友,肯定觉得 Go 标准库应该提供更多便利函数,让生活质量更好。在 Go 社区这么多年,也确实听到了不少这方面的声音。

但 Go 官方不会轻易增加一个功能。就 Cut 函数来说,官方做了详细调研、说明,具体可以参考这个 issue:bytes, strings: add Cut[1],可见 bytes 同样的增加了 Cut 函数。

有人提到,为什么不增加 LastCut?Russ Cox 的解释是,LastIndex 的调用次数明显少于 Index,因此暂不提供 LastCut。

做一个决定,不是瞎拍脑袋的~

参考资料

[1]

bytes, strings: add Cut: https://github.com/golang/go/issues/46336




往期推荐
  • Go1.18 快讯:废弃了这个 API


我是 polarisxu,北大硕士毕业,曾在 360 等知名互联网公司工作,10多年技术研发与架构经验!2012 年接触 Go 语言并创建了 Go 语言中文网!著有《Go语言编程之旅》、开源图书《Go语言标准库》等。


坚持输出技术(包括 Go、Rust 等技术)、职场心得和创业感悟!欢迎「polarisxu」一起成长!也欢迎加我好友交流:gopherstudio


相关资源