为什么Go中的“ Split”不是“ string”类型的成员函数?

时间:2018-09-30 06:33:52

标签: algorithm go

当您想使用一些特定的分隔符以不同的语言分割字符串时,以下是一些摘要:

# python
s = 'a,b,c,d,e'
tokens = s.split(',')

// javascript
let s = 'a,b,c,d,e'
let tokens = s.split(',')

// go
s := "a,b,c,d,e"
tokens := strings.Split(s, ",")

如您所见,“ split”是Python和Javascript中string类型的成员函数,但在Go中不是。 我想知道为什么会这样,就像CPP中的STL一样,为什么操纵类型实例的函数不是该类型的成员函数,在Go中实现它们似乎很容易,例如:

// go
func (s *string) Split(d string) []string {
  // here goes the code to split s with d given
}

采用这种方式设计的原因是什么?

1 个答案:

答案 0 :(得分:5)

  

如您所见,“ split”是python和javascript中string类型的成员函数,但在golang中不是。

从一开始就是如此:commit 729bc5c, Sept 2008, for Go1是第一次提及string Split()函数的提交。

  

基本字符串实用程序。

那些功能被认为是“实用程序”,而不是predeclared string type 'string' itself的一部分。

此后不久,在commit 0f7306b, March 2009, still Go1

中对此进行了记录
// Split returns the array representing the substrings of s separated by string sep. Adjacent
// occurrences of sep produce empty substrings.  If sep is empty, it is the same as Explode.
func Split(s, sep string) []string {

您可以在commit 5eae3b2, April 2009func LookPath(file string) (string, *os.Error) {中看到它的首次使用

对带有字节的字节使用相同的方法:commit 7893322, June 2009; Go1similar Split() function

  

添加一个类似于字符串包的字节包。

总体思路是:您可以更改该实用程序功能,而无需更改值类型本身。
参见commit 30533d6, June 2009

  

更改strings.Splitbytes.Split以采用最大子串count自变量。

func Split(s, sep []byte, n int) [][]byte

更剧烈的演变:commit ebb1566, June 2011

  

strings.Split:默认设置为全部拆分。
  将拆分的签名更改为无计数(假定为完全拆分),然后将计数为Split的现有SplitN重命名。

另一个想法是继续使用string,同时可能在不需要它们时删除对这些实用程序函数的依赖关系(如commit 35ace1d, Nov. 2009:“删除对strconvstrings“)

它还允许添加更多相关功能,而无需触及字符串本身。
请参见commit 5d436b9, Nov. 2009:第:= strings.SplitAfter(text, "\n", 0)行,它使用Split()

另一个优点:您可以独立于string本身来优化这些功能,从而可以将重复的'Split'功能替换为strings.Split()
参见commit f388119, March 2013, Go 1.1

  

go/printer:使用strings.Split代替专用代码

     

使用更快的字符串包,专用代码和字符串之间的区别在于噪音:

benchmark         old ns/op    new ns/op    delta
BenchmarkPrint     16724291     16686729   -0.22%

相反的情况也是如此:替换字符串。用更简单的代码分割,例如commit d0c9b40, Sept. 2015, Go 1.6

  

mime:删除单词解码中的分配。

     

这通过用简单的前缀/后缀检查和某些自定义切片替换对TODO的调用来修复(*WordDecoder).Decode中的strings.Split

     

基准测试结果

benchmark                    old ns/op     new ns/op     delta
BenchmarkQEncodeWord-8       740           693           -6.35%
BenchmarkQDecodeWord-8       1291          727           -43.69%
BenchmarkQDecodeHeader-8     1194          767           -35.76%

commit ecff943, Sept. 2017, Go 1.11中的相同想法)