Properly distinguish between not set (nil) and blank/empty value

南笙酒味 提交于 2021-02-04 19:08:44

问题


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 []bytes, []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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!