检查多个字符串是否为空的优雅方法

Elegant way to check if multiple strings are empty

如何优雅地检查多个字符串是否为空?我目前是这样做的:

//if one required field is empty, close the connection
    if (registerRequest.Email == "") ||
        (registerRequest.PhoneNumber == "")||
        (registerRequest.NachName =="") ||
        (registerRequest.VorName =="") ||
        (registerRequest.Password =="") ||
        (registerRequest.VerificationId ==""){

        //Could not proceed
        w.WriteHeader(UNABLE_TO_PROCEED)
        w.Write([]byte("Unable to register account."))
        return

    }

注意:如果您在处理程序中保留 "is-valid" 条件,并且将条件分离到另一个函数或方法中,则可以使用下面的解决方案。

您可以创建一个简单的辅助函数,它有一个可变参数,您可以使用任意数量的 string 值调用它:

func containsEmpty(ss ...string) bool {
    for _, s := range ss {
        if s == "" {
            return true
        }
    }
    return false
}

使用示例:

if containsEmpty("one", "two", "") {
    fmt.Println("One is empty!")
} else {
    fmt.Println("All is non-empty.")
}

if containsEmpty("one", "two", "three") {
    fmt.Println("One is empty!")
} else {
    fmt.Println("All is non-empty.")
}

上面的输出(在 Go Playground 上尝试):

One is empty!
All is non-empty.

您的示例如下所示:

if containsEmpty(registerRequest.Email,
    registerRequest.PhoneNumber,
    registerRequest.NachName,
    registerRequest.VorName,
    registerRequest.Password,
    registerRequest.VerificationId) {

    // One of the listed strings is empty
}

还有registerRequest这个名字有点长,可以缩短成r。如果你不能或不想在周围的代码中重命名它,如果你想缩短条件,你也可以这样做:

如果registerRequest是一个指针(或接口),你也可以这样写:

if r := registerRequest; containsEmpty(r.Email,
    r.PhoneNumber,
    r.NachName,
    r.VorName,
    r.Password,
    r.VerificationId) {

    // One of the listed strings is empty
}

实际上,即使 registerRequest 不是指针,您也可以这样做,但是结构将被复制。如果 registerRequest 是一个 struct,那么你可以获取它的地址以避免像这样复制它:

if r := &registerRequest; containsEmpty(r.Email,
    r.PhoneNumber,
    r.NachName,
    r.VorName,
    r.Password,
    r.VerificationId) {

    // One of the listed strings is empty
}

正如 Mario Santini 在评论中提到的那样,一种提高可测试性、封装此逻辑并将其与您的处理程序方法分离的方法(从字段的数量来看,它有可能以不同于你的处理程序)可以将这个逻辑放在一个函数中:

func validRequest(registerRequest ?) bool {
   return registerRequest.Email == "" ||
        registerRequest.PhoneNumber == "" ||
        registerRequest.NachName == "" ||
        registerRequest.VorName == "" ||
        registerRequest.Password == "" ||
        registerRequest.VerificationId == ""
}

这现在支持非常集中的、table 驱动的测试,它可以练习成为一个有效请求的意义,独立于任何涉及编写 headers.

的方法

它允许您验证封闭函数的 valid/invalid 路径,但要在此处进行非常有针对性的测试。它还允许您更改有效请求的含义,并独立于您的封闭函数对其进行验证。

您可以使用 switch:

switch "" {
case registerRequest.Email,
registerRequest.NachName,
registerRequest.Password,
registerRequest.PhoneNumber,
registerRequest.VerificationId,
registerRequest.VorName:
   w.WriteHeader(UNABLE_TO_PROCEED)
   w.Write([]byte("Unable to register account."))
   return
}

https://golang.org/ref/spec#Switch_statements