正确区分未设置(空)和空白/空值

时间:2014-05-18 23:23:52

标签: go

正确的方法是区分结构中的值何时从未设置,或者只是为空,例如,给定以下内容:

type Organisation struct {
    Category string
    Code     string
    Name     string
}

我需要知道(例如)该类别是否从未设置过,或者是否由用户保存为空白,我应该这样做:

type Organisation struct {
    Category *string
    Code     *string
    Name     *string
}

我还需要确保将null空字符串正确地保存到数据库

我还在学习GO所以我的问题完全有可能需要更多信息。

3 个答案:

答案 0 :(得分:6)

string的零值是一个空字符串,您无法区分这两者。

如果您使用的是database/sql软件包,并且需要区分NULL和空字符串,请考虑使用sql.NullString类型。它是一个跟踪NULL状态的简单结构:

type NullString struct {
        String string
        Valid  bool // Valid is true if String is not NULL
}

您可以扫描到此类型并将其用作查询参数,并且包将为您处理NULL状态。

答案 1 :(得分:5)

Google的协议缓冲区(https://code.google.com/p/goprotobuf/)使用指针来描述可选字段。

生成的对象提供GetFoo方法,可以避免测试nil(a.GetFoo()如果a.Foo为nil则返回空字符串,否则返回*a.Foo

当你想要编写文字结构时(例如在测试中),它会引入麻烦,因为&"something"不是生成指向字符串的指针的有效语法,所以你需要一个帮助函数(参见,for例如,the source code of the protocol buffer library for proto.String)。

// String is a helper routine that allocates a new string value
// to store v and returns a pointer to it.
func String(v string) *string {
        return &v
}

总的来说,使用指针来表示可选字段并非没有缺点,但它肯定是一个可行的设计选择。

答案 2 :(得分:4)

标准database/sql包提供NullString结构(成员只有String stringValid bool)。为了处理持久性的一些重复性工作,您可以查看像gorp这样的对象关系管理器。

我调查了是否有某种方法可以区分两种空字符串,只是出于好奇,而且找不到它。对于[]byte s,[]byte{} == []byte(nil)当前返回false,但我不确定规范是否保证始终保持为true。无论如何,看起来最实际的做法是使用流程并使用NullString