it-swarm.com.de

Was ist der beste Weg, um einen leeren String in Go zu testen?

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?

169
Richard

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.

264
ANisus

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.

25
zzzz

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!")
  }
}
13
Wilhelm Murdoch

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

10
Edwinner

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
}
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
}
0
Brian Leishman

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.

https://godbolt.org/z/fib1x1

0
Timmmm

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 {

        }
    }
}
0
Ketan Parmar