检查结构的多个属性的更惯用的方法?

Assume I have the following struct:

type myType struct {
    Qid, Interval, RoundNumber string
}

and I have to make sure that a variable of type myType does not have an empty string value for any of the properties.

Is there a more idiomatic way than doing the following if:

if aMyType.Qid == "" || aMyType.Interval == "" || aMyType.RoundNumber == "" {
  // handle error situation
}

Obviously the if works but I was wondering whether Go has a better way?

You might define a function on myType that would make it easier to determine validity:

func (m myType) Valid() bool {
    return m.Qid != "" && m.Interval != "" && m.RoundNumber != ""
}

And then:

if aMyType.Valid() {
    // ...
}

I won't claim it's idiomatic, but if you want to play around with reflection... You can dynamically inspect the exported (capital first letter) fields of a struct. This example inspects all of the exported strings in the struct for non-empty. This doesn't handle nested structs.

http://play.golang.org/p/IjMW8OJKlc

type myType struct {
    Number  int
    A, b, C string
}

This works by only checking for empty on exported string types.

func (m *myType) IsValid() bool {

    v := reflect.ValueOf(*m)

    for i := 0; i < v.NumField(); i++ {
        sv := v.Field(i)
        if sv.Kind() == reflect.String && sv.CanInterface() && sv.Interface() == "" {
            return false
        }
    }
    return true
}

func main() {
    // false
    fmt.Println((&myType{}).IsValid())
    // true
    fmt.Println((&myType{A: "abc", C: "123"}).IsValid())
}

For simple cases as you mentioned, I think the method you provided is more natural and more idiomatic in Go:

if mt.Qid == "" || mt.Interval == "" || mt.RoundNumber == "" {
    // handle error situation
}

But if your struct is non-trivial and the validation rule is complicated, then it may be more idiomatic to leverage a dedicated library such as validating. See here for a slightly more complex use-case, and here for a very complicated use-case.

As a contrast, by using validating, the validation rule you mentioned can be implemented as follows:

import v "github.com/RussellLuo/validating"

errs := v.Validate(v.Schema{
    v.F("qid", &mt.Qid):                  v.Nonzero(),
    v.F("interval", &mt.Interval):        v.Nonzero(),
    v.F("round_number", &mt.RoundNumber): v.Nonzero(),
})