由于空字符串是Golang的零/默认值,因此string我决定将所有这些字段定义为interface{}相反.例如
type student struct {
FirstName interface{} `json:"first_name"`
MiddleName interface{} `json:"middle_name"`
LastName interface{} `json:"last_name"`
}
Run Code Online (Sandbox Code Playgroud)
如果该特定字段的值不可用,则我发送数据的应用程序需要null而不是空字符串.
这是正确的方法还是有人可以指点我比这更好的东西.
Asd*_*ine 59
在json包文档中:
指针值编码为指向的值.nil指针编码为null JSON对象.
所以你可以存储一个指向字符串的指针,如果不是nil将被编码为字符串,如果为nil将被编码为"null"
type student struct {
FirstName *string `json:"first_name"`
MiddleName *string `json:"middle_name"`
LastName *string `json:"last_name"`
}
Run Code Online (Sandbox Code Playgroud)
小智 8
可以使用https://github.com/guregu/null
type student struct {
FirstName null.String `json:"first_name"`
MiddleName null.String `json:"middle_name"`
LastName null.String `json:"last_name"`}
Run Code Online (Sandbox Code Playgroud)
您可以使用sql.NullString之类的东西,使用 'Valid' 来检查它是否为 nil 值。
NullString 表示可能为空的字符串。NullString 实现 Scanner 接口,因此它可以用作扫描目标:
type NullString struct {
String string
Valid bool // Valid is true if String is not NULL
}
var s NullString
err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
...
if s.Valid {
// use s.String
} else {
// NULL value
}
Run Code Online (Sandbox Code Playgroud)
请不要使用如下指针:
type student struct {
FirstName *string `json:"first_name"`
MiddleName *string `json:"middle_name"`
LastName *string `json:"last_name"`
}
Run Code Online (Sandbox Code Playgroud)
因为你需要检查 nil 值并像下面这样到处取消引用,并且可能会在某处导致意外崩溃:
if obj.FirstName != nil {
fmt.Print("%s", *obj.FirstName)
}
Run Code Online (Sandbox Code Playgroud)
我比较了两种解决方案,并在我广泛的生产代码中选择前一种方法......它工作正常。
小智 6
另一种方法实际上是使用 golang 的 json 库提供的 MarhshalJSON 和 UnmarshalJSON 接口方法的解决方法。代码如下:
type MyType string
type MyStruct struct {
A MyType `json:"my_type"`
}
func (c MyType) MarshalJSON() ([]byte, error) {
var buf bytes.Buffer
if len(string(c)) == 0 {
buf.WriteString(`null`)
} else {
buf.WriteString(`"` + string(c) + `"`) // add double quation mark as json format required
}
return buf.Bytes(), nil
}
func (c *MyType)UnmarshalJSON(in []byte) error {
str := string(in)
if str == `null` {
*c = ""
return nil
}
res := MyType(str)
if len(res) >= 2 {
res = res[1:len(res)-1] // remove the wrapped qutation
}
*c = res
return nil
}
Run Code Online (Sandbox Code Playgroud)
那么当使用 json.Marshal 时,MyType 值将被编组为 null。
对于带有空字符串的 json 对象,最容易在字段上使用 omitempty 装饰器。
type student struct {
FirstName string `json:"first_name,omitempty"`
MiddleName string `json:"middle_name,omitempty"`
LastName string `json:"last_name"`
}
Run Code Online (Sandbox Code Playgroud)
使用上面的声明,仅当分配了 first_name 时,该键才会显示在结果 json 中。另一方面,如果未分配,last_name 将始终显示在结果中,其值为“”。
现在,当您开始包含 0 可能是值的数字字段时,使用 omitempty 并不能满足人们的预期。0 值总是丢弃该字段,我们需要能够区分 0 值和未分配的值。在这里使用诸如此类的库https://github.com/guregu/null可能是可取的。
更多讨论在这里:https : //www.sohamkamani.com/blog/golang/2018-07-19-golang-omitempty/