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

时间:2014-02-28 15:18:05

标签: go

假设我有以下结构:

type myType struct {
    Qid, Interval, RoundNumber string
}

我必须确保myType类型的变量没有任何属性的空字符串值。

是否存在比以下

更为惯用的方法
if aMyType.Qid == "" || aMyType.Interval == "" || aMyType.RoundNumber == "" {
  // handle error situation
}

显然,如果有效,但我想知道Go是否有更好的方法?

3 个答案:

答案 0 :(得分:8)

您可以在myType上定义一个可以更容易确定有效性的函数:

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

然后:

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

答案 1 :(得分:1)

我不会声称它是惯用的,但是如果你想玩反射......你可以动态检查结构的导出(首字母大写)字段。此示例检查结构中的所有导出字符串是否为非空。这不处理嵌套的结构。

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

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

这只能检查导出的字符串类型是否为空。

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())
}

答案 2 :(得分:0)

对于您提到的简单案例,我认为您提供的方法在Go中更自然,更具惯用性:

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

但是如果您的结构非常重要且验证规则很复杂,那么利用validating等专用库可能更为惯用。有关更复杂的用例,请参阅here;对于非常复杂的用例,请参阅here

作为对比,通过使用validating,您提到的验证规则可以实现如下:

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(),
})