web-dev-qa-db-ja.com

Goで空の文字列をテストするための最良の方法は何ですか?

空でない文字列をテストするには(Goで)どの方法が最善でしょうか?

if len(mystring) > 0 { }

または

if mystring != "" { }

または、他の何か?

193
Richard

どちらのスタイルもGoの標準ライブラリ内で使われています。

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

strconvパッケージにあります。 http://golang.org/src/pkg/strconv/atoi.go

if s != "" { ... }

encoding/jsonパッケージにあります。 http://golang.org/src/pkg/encoding/json/encode.go

どちらも慣用句であり、十分に明確です。それはもっと個人的な好みの問題でありそして明快さについてである。

Russ Coxは、 ゴランナッツスレッド で次のように書き込みます。

コードを明確にするもの。
もし要素xを見ようとしているなら、私はたいてい書く
len(s)> x、x == 0の場合でも
「これはこの特定の文字列です」.

成熟したコンパイラがコンパイルすると仮定するのは合理的です
len(s)== 0とs == ""を同じ効率的なコードに変換します。
現在、6gなどはs == ""を関数呼び出しにコンパイルします。
len(s)== 0はそうではありませんが、それが私のやるべきことのリストに載っています。

コードを明確にします。

286
ANisus

これは時期尚早のミクロ最適化のようです。どちらの場合も、少なくともこれら2つの場合は、コンパイラが同じコードを自由に生成できます。

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

そして

if s != "" { ... }

意味が明らかに等しいからです。

25
zzzz

長さをチェックするのは良い答えですが、空白だけの「空の」文字列を考慮することもできます。 「技術的に」空ではありませんが、確認したい場合は、

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

空のスペースと前後のすべてのホワイトスペースを削除するとします。

import "strings"
if len(strings.TrimSpace(s)) == 0 { ... }

なぜなら
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2

8
Edwinner

現在のところ、Goコンパイラはどちらの場合も同じコードを生成するので、好みの問題です。 GCCGoは別のコードを生成しますが、ほとんど誰もそれを使用しないので、私はそれについて心配しません。

https://godbolt.org/z/fib1x1

1
Timmmm

以下のような関数を使用すると、よりクリーンでエラーが少なくなります。

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

これは、文字列全体をトリミングするよりもパフォーマンスがよくなります。これは、少なくとも1つのスペース以外の文字が存在することを確認するだけでよいためです。

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

私は最良の方法は空白の文字列と比較することだと思います

BenchmarkStringCheck1は空白文字列でチェックしています

BenchmarkStringCheck2はlenゼロでチェックしています

私は空と空でない文字列チェックでチェックします。空白の文字列で確認するほうが速いことがわかります。

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

コード

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