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?
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.
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.
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!")
}
}
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
}
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
}
À 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.
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 {
}
}
}