英文:
Properly distinguish between not set (nil) and blank/empty value
问题
在Go语言中,区分结构体中的值是未设置还是为空的正确方式是使用指针类型。例如,给定以下结构体:
type Organisation struct {
Category *string
Code *string
Name *string
}
如果需要知道某个字段是未设置还是被用户保存为空白值,可以将该字段声明为指针类型。如果字段的指针为nil
,则表示该字段未设置;如果字段的指针非nil
,但指向的值为空字符串,则表示该字段被保存为空白值。
同时,为了正确地将null
或空字符串持久化到数据库中,可以根据字段的指针值进行判断和处理。如果字段的指针为nil
,则将其持久化为null
;如果字段的指针非nil
,但指向的值为空字符串,则将其持久化为空字符串。
希望对你有帮助!如果你还有其他问题,请随时提问。
英文:
Whats the correct way in go to distinguish between when a value in a struct was never set, or is just empty, for example, given the following:
type Organisation struct {
Category string
Code string
Name string
}
I need to know (for example) if the category was never set, or was saved as blank by the user, should I be doing this:
type Organisation struct {
Category *string
Code *string
Name *string
}
I also need to ensure I correctly persist either null
or an empty string to the database
I'm still learning GO so it is entirely possible my question needs more info.
答案1
得分: 6
string
类型的零值是空字符串,你无法区分这两者。
如果你正在使用database/sql
包,并且需要区分NULL
和空字符串,可以考虑使用sql.NullString
类型。它是一个简单的结构体,用于跟踪NULL
状态:
type NullString struct {
String string
Valid bool // 如果String不为NULL,则Valid为true
}
你可以将数据扫描到这个类型中,并将其用作查询参数,database/sql
包会为你处理NULL
状态。
英文:
The zero value for a string
is an empty string, and you can't distinguish between the two.
If you are using the database/sql
package, and need to distinguish between NULL
and empty strings, consider using the sql.NullString
type. It is a simple struct that keeps track of the NULL
state:
type NullString struct {
String string
Valid bool // Valid is true if String is not NULL
}
You can scan into this type and use it as a query parameter, and the package will handle the NULL
state for you.
答案2
得分: 5
Google的协议缓冲区(https://code.google.com/p/goprotobuf/)使用指针来描述可选字段。
生成的对象提供了GetFoo
方法,它可以避免测试nil值的繁琐(如果a.Foo
为nil,则a.GetFoo()
返回一个空字符串,否则返回*a.Foo
)。
当你想要编写字面结构体时(例如在测试中),这会引入一些麻烦,因为&"something"
不是生成指向字符串的指针的有效语法,所以你需要一个辅助函数(参见,例如,协议缓冲区库的proto.String
源代码)。
// String是一个辅助函数,它分配一个新的字符串值来存储v,并返回指向它的指针。
func String(v string) *string {
return &v
}
总的来说,使用指针来表示可选字段并不是没有缺点的,但它肯定是一个可行的设计选择。
英文:
Google's protocol buffers (https://code.google.com/p/goprotobuf/) use pointers to describe optional fields.
The generated objects provide GetFoo
methods which take the pain away from testing for nil (a.GetFoo()
returns an empty string if a.Foo
is nil, otherwise it returns *a.Foo
).
It introduces a nuisance when you want to write literal structs (in tests, for example), because &"something"
is not valid syntax to generate a pointer to a string, so you need a helper function (see, for example, 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
}
Overall, using pointers to represent optional fields is not without drawbacks, but it's certainly a viable design choice.
答案3
得分: 4
标准的database/sql
包提供了一个NullString
结构体(成员只有String string
和Valid bool
)。为了处理一些重复的持久化工作,你可以考虑使用一个对象关系管理器,比如gorp。
我曾经调查过是否有一种方法可以区分两种类型的空字符串,只是出于好奇,并没有找到。对于[]byte
,[]byte{} == []byte(nil)
目前返回false,但我不确定规范是否保证这一点始终为真。无论如何,似乎最实际的做法是顺其自然,使用NullString
。
英文:
The standard database/sql
package provides a NullString
struct (members are just String string
and Valid bool
). To take care of some of the repetitive work of persistence, you could look at an object-relational manager like gorp.
I looked into whether there was some way to distinguish two kinds of empty string just out of curiosity, and couldn't find one. With []byte
s, []byte{} == []byte(nil)
currently returns false, but I'm not sure if the spec guarantees that to always remain true. In any case, it seems like the most practical thing to do is to go with the flow and use NullString
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论