正确的方法是区分结构中的值何时从未设置,或者只是为空,例如,给定以下内容:
type Organisation struct {
Category string
Code string
Name string
}
我需要知道(例如)该类别是否从未设置过,或者是否由用户保存为空白,我应该这样做:
type Organisation struct {
Category *string
Code *string
Name *string
}
我还需要确保将null
或空字符串正确地保存到数据库
我还在学习GO所以我的问题完全有可能需要更多信息。
答案 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 string
和Valid bool
)。为了处理持久性的一些重复性工作,您可以查看像gorp这样的对象关系管理器。
我调查了是否有某种方法可以区分两种空字符串,只是出于好奇,而且找不到它。对于[]byte
s,[]byte{} == []byte(nil)
当前返回false,但我不确定规范是否保证始终保持为true。无论如何,看起来最实际的做法是使用流程并使用NullString
。