mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
strings: improve explode and correct comment
Merges explodetests into splittests which already contain some of the tests that cover explode. Adds a test to cover the utf8.RuneError branch in explode. name old time/op new time/op delta Split1-2 14.9ms ± 0% 14.2ms ± 0% -4.06% (p=0.000 n=47+49) Change-Id: I00f796bd2edab70e926ea9e65439d820c6a28254 Reviewed-on: https://go-review.googlesource.com/21609 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
parent
3f66d8c84b
commit
819e0b29bb
2 changed files with 18 additions and 46 deletions
|
|
@ -12,32 +12,25 @@ import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
)
|
)
|
||||||
|
|
||||||
// explode splits s into an array of UTF-8 sequences, one per Unicode character (still strings) up to a maximum of n (n < 0 means no limit).
|
// explode splits s into a slice of UTF-8 strings,
|
||||||
// Invalid UTF-8 sequences become correct encodings of U+FFF8.
|
// one string per Unicode character up to a maximum of n (n < 0 means no limit).
|
||||||
|
// Invalid UTF-8 sequences become correct encodings of U+FFFD.
|
||||||
func explode(s string, n int) []string {
|
func explode(s string, n int) []string {
|
||||||
if n == 0 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
l := utf8.RuneCountInString(s)
|
l := utf8.RuneCountInString(s)
|
||||||
if n <= 0 || n > l {
|
if n < 0 || n > l {
|
||||||
n = l
|
n = l
|
||||||
}
|
}
|
||||||
a := make([]string, n)
|
a := make([]string, n)
|
||||||
var size int
|
for i := 0; i < n-1; i++ {
|
||||||
var ch rune
|
ch, size := utf8.DecodeRuneInString(s)
|
||||||
i, cur := 0, 0
|
a[i] = s[:size]
|
||||||
for ; i+1 < n; i++ {
|
s = s[size:]
|
||||||
ch, size = utf8.DecodeRuneInString(s[cur:])
|
|
||||||
if ch == utf8.RuneError {
|
if ch == utf8.RuneError {
|
||||||
a[i] = string(utf8.RuneError)
|
a[i] = string(utf8.RuneError)
|
||||||
} else {
|
|
||||||
a[i] = s[cur : cur+size]
|
|
||||||
}
|
}
|
||||||
cur += size
|
|
||||||
}
|
}
|
||||||
// add the rest, if there is any
|
if n > 0 {
|
||||||
if cur < len(s) {
|
a[n-1] = s
|
||||||
a[i] = s[cur:]
|
|
||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -256,31 +256,6 @@ func BenchmarkIndexByte(b *testing.B) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var explodetests = []struct {
|
|
||||||
s string
|
|
||||||
n int
|
|
||||||
a []string
|
|
||||||
}{
|
|
||||||
{"", -1, []string{}},
|
|
||||||
{abcd, 4, []string{"a", "b", "c", "d"}},
|
|
||||||
{faces, 3, []string{"☺", "☻", "☹"}},
|
|
||||||
{abcd, 2, []string{"a", "bcd"}},
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestExplode(t *testing.T) {
|
|
||||||
for _, tt := range explodetests {
|
|
||||||
a := SplitN(tt.s, "", tt.n)
|
|
||||||
if !eq(a, tt.a) {
|
|
||||||
t.Errorf("explode(%q, %d) = %v; want %v", tt.s, tt.n, a, tt.a)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
s := Join(a, "")
|
|
||||||
if s != tt.s {
|
|
||||||
t.Errorf(`Join(explode(%q, %d), "") = %q`, tt.s, tt.n, s)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type SplitTest struct {
|
type SplitTest struct {
|
||||||
s string
|
s string
|
||||||
sep string
|
sep string
|
||||||
|
|
@ -289,19 +264,23 @@ type SplitTest struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
var splittests = []SplitTest{
|
var splittests = []SplitTest{
|
||||||
|
{"", "", -1, []string{}},
|
||||||
|
{abcd, "", 2, []string{"a", "bcd"}},
|
||||||
|
{abcd, "", 4, []string{"a", "b", "c", "d"}},
|
||||||
|
{abcd, "", -1, []string{"a", "b", "c", "d"}},
|
||||||
|
{faces, "", -1, []string{"☺", "☻", "☹"}},
|
||||||
|
{faces, "", 3, []string{"☺", "☻", "☹"}},
|
||||||
|
{faces, "", 17, []string{"☺", "☻", "☹"}},
|
||||||
|
{"☺<>☹", "", -1, []string{"☺", "<22>", "☹"}},
|
||||||
{abcd, "a", 0, nil},
|
{abcd, "a", 0, nil},
|
||||||
{abcd, "a", -1, []string{"", "bcd"}},
|
{abcd, "a", -1, []string{"", "bcd"}},
|
||||||
{abcd, "z", -1, []string{"abcd"}},
|
{abcd, "z", -1, []string{"abcd"}},
|
||||||
{abcd, "", -1, []string{"a", "b", "c", "d"}},
|
|
||||||
{commas, ",", -1, []string{"1", "2", "3", "4"}},
|
{commas, ",", -1, []string{"1", "2", "3", "4"}},
|
||||||
{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
|
{dots, "...", -1, []string{"1", ".2", ".3", ".4"}},
|
||||||
{faces, "☹", -1, []string{"☺☻", ""}},
|
{faces, "☹", -1, []string{"☺☻", ""}},
|
||||||
{faces, "~", -1, []string{faces}},
|
{faces, "~", -1, []string{faces}},
|
||||||
{faces, "", -1, []string{"☺", "☻", "☹"}},
|
|
||||||
{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
|
{"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}},
|
||||||
{"1 2", " ", 3, []string{"1", "2"}},
|
{"1 2", " ", 3, []string{"1", "2"}},
|
||||||
{"123", "", 2, []string{"1", "23"}},
|
|
||||||
{"123", "", 17, []string{"1", "2", "3"}},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSplit(t *testing.T) {
|
func TestSplit(t *testing.T) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue