This question already has an answer here:
Here are some snippets when you want to split a string with some specific delimiter in different languages:
# 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, ",")
As you can see, "split" is a member function of type string in Python and Javascript, but not in Go. I am wondering why is that, it seems like STL in CPP, why the functions to manipulate an instance of a type are not member functions of that type, it seems easy to implement them in Go, like:
// go
func (s *string) Split(d string) []string {
// here goes the code to split s with d given
}
what is the reason it is designed this way?
</div>
As you can see, "split" is a member function of type string in python and javascript, but not in golang.
That seems to have been so from the very beginning: commit 729bc5c, Sept 2008, for Go1 is the first commit with any mention of a string Split()
function.
rudimentary string utilities.
Those functions were considered "utilities", and not part of the predeclared string type 'string
' itself.
It was documented soon after in 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 {
You can see it used for the first time in commit 5eae3b2, April 2009 in func LookPath(file string) (string, *os.Error) {
The same approach was use for byte with bytes: commit 7893322, June 2009; Go1, with a similar Split() function.
add a bytes package analogous to the strings package.
The general idea is: you can change that utility function without changing the value type itself.
See commit 30533d6, June 2009:
Change
strings.Split
,bytes.Split
to take a maximum substringcount
argument.func Split(s, sep []byte, n int) [][]byte
An even more drastic evolution:commit ebb1566, June 2011
strings.Split
: make the default to split all.
Change the signature of Split to have no count, assuming a full split, and rename the existingSplit
with a count toSplitN
.
The other idea is to keep using string
, while possibly removing dependencies to those utility functions when you don't need them (as in commit 35ace1d, Nov. 2009: "remove dependencies on strconv
and strings
")
It also allows to add more related function, without touching string itself.
See commit 5d436b9, Nov. 2009: lines := strings.SplitAfter(text, " ", 0)
, which uses Split()
.
Another advantage: you can optimize those functions independently of string
itself, allowing for duplicate 'Split' function to be replaced by strings.Split()
.
See commit f388119, March 2013, Go 1.1
go/printer
: usestrings.Split
instead of specialized codeWith the faster strings package, the difference between the specialized code and strings.Split is in the noise:
benchmark old ns/op new ns/op delta BenchmarkPrint 16724291 16686729 -0.22%
The opposite case is also true: replacing strings.Split by a simpler code, as in commit d0c9b40, Sept. 2015, Go 1.6
mime: Remove an allocation in word decoding.
This fixes a
TODO
in(*WordDecoder).Decode
by replacing a call tostrings.Split
with simple prefix/suffix checking and some custom slicing.Benchmark results:
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%
(same idea in commit ecff943, Sept. 2017, Go 1.11)