From 819e0b29bbbc07022e7b94c12b55860466a02e5b Mon Sep 17 00:00:00 2001 From: =?utf8?q?Martin=20Mo=CC=88hrmann?= Date: Sat, 26 Mar 2016 00:04:48 +0100 Subject: [PATCH] strings: improve explode and correct comment MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 TryBot-Result: Gobot Gobot Reviewed-by: Ian Lance Taylor --- src/strings/strings.go | 27 ++++++++++----------------- src/strings/strings_test.go | 37 ++++++++----------------------------- 2 files changed, 18 insertions(+), 46 deletions(-) diff --git a/src/strings/strings.go b/src/strings/strings.go index c24c77b9dd..919e8c8354 100644 --- a/src/strings/strings.go +++ b/src/strings/strings.go @@ -12,32 +12,25 @@ import ( "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). -// Invalid UTF-8 sequences become correct encodings of U+FFF8. +// explode splits s into a slice of UTF-8 strings, +// 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 { - if n == 0 { - return nil - } l := utf8.RuneCountInString(s) - if n <= 0 || n > l { + if n < 0 || n > l { n = l } a := make([]string, n) - var size int - var ch rune - i, cur := 0, 0 - for ; i+1 < n; i++ { - ch, size = utf8.DecodeRuneInString(s[cur:]) + for i := 0; i < n-1; i++ { + ch, size := utf8.DecodeRuneInString(s) + a[i] = s[:size] + s = s[size:] if ch == utf8.RuneError { a[i] = string(utf8.RuneError) - } else { - a[i] = s[cur : cur+size] } - cur += size } - // add the rest, if there is any - if cur < len(s) { - a[i] = s[cur:] + if n > 0 { + a[n-1] = s } return a } diff --git a/src/strings/strings_test.go b/src/strings/strings_test.go index 0572adbdd9..1ed803bf85 100644 --- a/src/strings/strings_test.go +++ b/src/strings/strings_test.go @@ -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 { s string sep string @@ -289,19 +264,23 @@ type SplitTest struct { } 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{"☺", "�", "☹"}}, {abcd, "a", 0, nil}, {abcd, "a", -1, []string{"", "bcd"}}, {abcd, "z", -1, []string{"abcd"}}, - {abcd, "", -1, []string{"a", "b", "c", "d"}}, {commas, ",", -1, []string{"1", "2", "3", "4"}}, {dots, "...", -1, []string{"1", ".2", ".3", ".4"}}, {faces, "☹", -1, []string{"☺☻", ""}}, {faces, "~", -1, []string{faces}}, - {faces, "", -1, []string{"☺", "☻", "☹"}}, {"1 2 3 4", " ", 3, []string{"1", "2", "3 4"}}, {"1 2", " ", 3, []string{"1", "2"}}, - {"123", "", 2, []string{"1", "23"}}, - {"123", "", 17, []string{"1", "2", "3"}}, } func TestSplit(t *testing.T) { -- 2.48.1