web-dev-qa-db-fra.com

Quel est le meilleur moyen de tester une chaîne vide dans Go?

Quelle est la meilleure méthode (plus idomatic) pour tester des chaînes non vides (en Go)?

if len(mystring) > 0 { }

Ou:

if mystring != "" { }

Ou autre chose?

169
Richard

Les deux styles sont utilisés dans les bibliothèques standard de Go.

if len(s) > 0 { ... }

peut être trouvé dans le paquet strconv: http://golang.org/src/pkg/strconv/atoi.go

if s != "" { ... }

peut être trouvé dans le paquet encoding/json: http://golang.org/src/pkg/encoding/json/encode.go

Les deux sont idiomatiques et suffisamment clairs. C'est plus une question de goût personnel et de clarté.

Russ Cox écrit dans un filetage - golang-nuts :

Celui qui rend le code clair.
Si je suis sur le point de regarder l'élément x, j'écris généralement
len (s)> x, même pour x == 0, mais si je me soucie de
"Est-ce cette chaîne spécifique" J'ai tendance à écrire s == "". 

Il est raisonnable de supposer qu'un compilateur mature compilera
len (s) == 0 et s == "" dans le même code efficace.
Actuellement, 6g, etc., compilons s == "" dans un appel de fonction
tandis que len (s) == 0 n'est pas, mais cela a été sur ma liste de tâches à résoudre. 

Rendre le code clair.

264
ANisus

Cela semble être une microoptimisation prématurée. Le compilateur est libre de produire le même code pour les deux cas ou au moins pour ces deux cas.

if len(s) != 0 { ... }

et

if s != "" { ... }

parce que la sémantique est clairement égale.

25
zzzz

La vérification de la longueur est une bonne réponse, mais vous pouvez également prendre en compte une chaîne "vide" qui n'est également qu'un espace. Pas "techniquement" vide, mais si vous voulez vérifier:

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

Il serait plus propre et moins sujet aux erreurs d'utiliser une fonction comme celle ci-dessous:

func empty(s string) bool {
    return len(strings.TrimSpace(s)) == 0
}
0
Yannis Sermetziadis

Ce serait plus performant que de couper la chaîne entière, puisqu'il suffit de vérifier au moins un seul caractère non-espace 

// 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

À partir de maintenant, le compilateur Go génère un code identique dans les deux cas, c'est donc une question de goût. GCCGo génère un code différent, mais presque personne ne l'utilise, je ne m'inquiéterais donc pas.

https://godbolt.org/z/fib1x1

0
Timmmm

Je pense que le meilleur moyen est de comparer avec une chaîne vide

BenchmarkStringCheck1 vérifie avec une chaîne vide

BenchmarkStringCheck2 vérifie avec len zéro

Je vérifie avec la vérification de chaîne vide et non-vide. Vous pouvez voir que vérifier avec une chaîne vide est plus rapide.

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