Welche Methode eignet sich am besten für das Testen nicht leerer Zeichenfolgen (in Go)?
if len(mystring) > 0 { }
Oder:
if mystring != "" { }
Oder etwas anderes?
Beide Stile werden in den Standardbibliotheken von Go verwendet.
if len(s) > 0 { ... }
ist im Paket strconv
enthalten: http://golang.org/src/pkg/strconv/atoi.go
if s != "" { ... }
finden Sie im encoding/json
-Paket: http://golang.org/src/pkg/encoding/json/encode.go
Beide sind idiomatisch und klar genug. Es ist eher eine Frage des persönlichen Geschmacks und der Klarheit.
Russ Cox schreibt in einem Golang-Muttern-Gewinde :
Derjenige, der den Code klar macht.
Wenn ich Element x anschaue, schreibe ich normalerweise
len (s)> x, auch für x == 0, aber wenn es mich interessiert
"Ist es diese bestimmte Zeichenfolge", neige ich dazu, s == "" zu schreiben.Es ist vernünftig anzunehmen, dass ein ausgereifter Compiler kompiliert wird
len (s) == 0 und s == "" in den gleichen, effizienten Code.
Im Moment kompilieren 6g usw. s == "" in einen Funktionsaufruf
len (s) == 0 ist zwar nicht, aber das war auf meiner To-Do-Liste, um das Problem zu beheben.Machen Sie den Code klar.
Dies scheint eine vorzeitige Mikrooptimierung zu sein. Der Compiler kann in beiden Fällen oder zumindest in beiden Fällen denselben Code erzeugen
if len(s) != 0 { ... }
und
if s != "" { ... }
weil die Semantik eindeutig gleich ist.
Das Überprüfen der Länge ist eine gute Antwort, aber Sie könnten auch eine "leere" Zeichenfolge berücksichtigen, die nur Leerzeichen ist. Nicht "technisch" leer, aber wenn Sie Folgendes prüfen:
package main
import (
"fmt"
"strings"
)
func main() {
stringOne := "merpflakes"
stringTwo := " "
stringThree := ""
if len(strings.TrimSpace(stringOne)) == 0 {
fmt.Println("String is empty!")
}
if len(strings.TrimSpace(stringTwo)) == 0 {
fmt.Println("String two is empty!")
}
if len(stringTwo) == 0 {
fmt.Println("String two is still empty!")
}
if len(strings.TrimSpace(stringThree)) == 0 {
fmt.Println("String three is empty!")
}
}
Angenommen, leere Leerzeichen und alle führenden und nachfolgenden Leerzeichen sollten entfernt werden:
import "strings"
if len(strings.TrimSpace(s)) == 0 { ... }
Weil :len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2
Es wäre sauberer und weniger fehleranfällig, eine Funktion wie die folgende zu verwenden:
func empty(s string) bool {
return len(strings.TrimSpace(s)) == 0
}
Dies wäre leistungsfähiger als das Beschneiden der gesamten Zeichenfolge, da Sie nur nach einem einzigen nicht-Leerzeichen-Zeichen suchen müssen
// Strempty checks whether string contains only whitespace or not
func Strempty(s string) bool {
if len(s) == 0 {
return true
}
r := []rune(s)
l := len(r)
for l > 0 {
l--
if !unicode.IsSpace(r[l]) {
return false
}
}
return true
}
Der Go-Compiler generiert ab sofort in beiden Fällen identischen Code, es ist also Geschmackssache. GCCGo generiert einen anderen Code, aber kaum jemand verwendet ihn, sodass ich mir keine Sorgen machen muss.
Ich denke, der beste Weg ist es, mit einer leeren Zeichenkette zu vergleichen
BenchmarkStringCheck1 prüft mit leerer Zeichenfolge
BenchmarkStringCheck2 prüft mit len zero
Ich überprüfe mit der leeren und nicht leeren Zeichenfolge. Sie sehen, dass das Überprüfen mit einer leeren Zeichenfolge schneller ist.
BenchmarkStringCheck1-4 2000000000 0.29 ns/op 0 B/op 0 allocs/op
BenchmarkStringCheck1-4 2000000000 0.30 ns/op 0 B/op 0 allocs/op
BenchmarkStringCheck2-4 2000000000 0.30 ns/op 0 B/op 0 allocs/op
BenchmarkStringCheck2-4 2000000000 0.31 ns/op 0 B/op 0 allocs/op
Code
func BenchmarkStringCheck1(b *testing.B) {
s := "Hello"
b.ResetTimer()
for n := 0; n < b.N; n++ {
if s == "" {
}
}
}
func BenchmarkStringCheck2(b *testing.B) {
s := "Hello"
b.ResetTimer()
for n := 0; n < b.N; n++ {
if len(s) == 0 {
}
}
}