在Golang

时间:2015-06-25 11:04:15

标签: go

由于空字符串是Golang string的零/默认值,我决定将所有这些字段定义为interface{}。例如

type student struct {
    FirstName  interface{} `json:"first_name"`
    MiddleName interface{} `json:"middle_name"`
    LastName   interface{} `json:"last_name"`
}

如果该特定字段的值不可用,我发送数据的应用程序需要null而不是空字符串。

这是正确的做法还是有人可以指点我比这更好的东西。

5 个答案:

答案 0 :(得分:52)

json package documentation中:

  

指针值编码为指向的值。 nil指针编码为空JSON对象。

所以你可以存储一个指向字符串的指针,如果不是nil将被编码为字符串,如果为nil将被编码为“null”

type student struct {
  FirstName  *string `json:"first_name"`
  MiddleName *string `json:"middle_name"`
  LastName   *string `json:"last_name"`
}

答案 1 :(得分:2)

可以使用Math.floor

import numpy as np
import matplotlib.pyplot as plt


def f(x):
    return ((x) * np.sqrt((x) + 0.5) * ((x) + 1))


x = np.linspace(-4, -2, 10).astype(np.complex)
y = f(x)

plt.plot(y.real, y.imag,'*')
for i in range(x.shape[0]):
    plt.text(y.real[i], y.imag[i],"x="+str(x.real[i]))
plt.title('sample')
plt.xlabel('y real')
plt.ylabel('y imag')
plt.show()

答案 2 :(得分:2)

您可以使用类似sql.NullString的东西,使用'Valid'来检查它是否为零。

NullString表示可能为空的字符串。 NullString实现 扫描仪界面,因此可以用作扫描目标:

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
}

请勿使用如下指针:

type student struct {
  FirstName  *string `json:"first_name"`
  MiddleName *string `json:"middle_name"`
  LastName   *string `json:"last_name"`
}

因为您需要像以下各处一样检查nil值和取消引用,并且可能在某处导致意外崩溃:

if obj.FirstName != nil {
   fmt.Print("%s", *obj.FirstName)
}

我在广泛的生产代码中比较了两种解决方案,并选择了以前的方法,效果很好。

答案 3 :(得分:1)

另一种方法实际上是使用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
}

然后使用json.Marshal时,MyType值将被整理为null。

答案 4 :(得分:1)

对于具有空字符串的json对象,最容易在字段上使用省略号修饰符。

type student struct {
  FirstName  string `json:"first_name,omitempty"`
  MiddleName string `json:"middle_name,omitempty"`
  LastName   string `json:"last_name"`
}

使用上面的声明,只有指定了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/