在 Go 中测试空字符串的最佳方法是什么?

问题描述:

Which method is best (more idomatic) for testing non-empty strings (in Go)?

if len(mystring) > 0 { }

Or:

if mystring != "" { }

Or something else?

转载于:https://*.com/questions/18594330/what-is-the-best-way-to-test-for-an-empty-string-in-go

Both styles are used within the Go's standard libraries.

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

can be found in the strconv package: http://golang.org/src/pkg/strconv/atoi.go

if s != "" { ... }

can be found in the encoding/json package: http://golang.org/src/pkg/encoding/json/encode.go

Both are idiomatic and are clear enough. It is more a matter of personal taste and about clarity.

Russ Cox writes in a golang-nuts thread:

The one that makes the code clear.
If I'm about to look at element x I typically write
len(s) > x, even for x == 0, but if I care about
"is it this specific string" I tend to write s == "".

It's reasonable to assume that a mature compiler will compile
len(s) == 0 and s == "" into the same, efficient code.
Right now 6g etc do compile s == "" into a function call
while len(s) == 0 is not, but that's been on my to-do list to fix.

Make the code clear.

This seems to be premature microoptimization. The compiler is free to produce the same code for both cases or at least for these two

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

and

if s != "" { ... }

because the semantics is clearly equal.

Checking for length is a good answer, but you could also account for an "empty" string that is also only whitespace. Not "technically" empty, but if you care to check:

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

Assuming that empty spaces and all leading and trailing white spaces should be removed:

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

Because :
len("") // is 0
len(" ") // one empty space is 1
len(" ") // two empty spaces is 2

It would be cleaner and less error-prone to use a function like the one below:

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

This would be more performant than trimming the whole string, since you only need to check for at least a single non-space character existing

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