问题
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:
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:
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:
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
.
来源:https://stackoverflow.com/questions/23727866/properly-distinguish-between-not-set-nil-and-blank-empty-value