一尘不染

如何在Go中使用非必需的JSON参数?

go

嗨,我正在Go中使用rest API,我希望用户传递JSON参数:

Offset int64  `json:"offset"`
Limit  int64  `json:"limit"`
SortBy string `json:"sortby"`
Asc    bool   `json:"asc"`
Username   string `json:"username"`
First_Name string `json:"first_name"`
Last_Name  string `json:"last_name"`
Status     string `json:"status"`

但是它们并非总是必需的,例如,用户只能通过Offset而忽略其他用户。他甚至可以发送0个参数。我怎样才能做到这一点?


阅读 376

收藏
2020-07-02

共1个答案

一尘不染

从JSON文本解组值时,json程序包不需要所有字段都以JSON形式出现,也不需要所有JSON字段都具有匹配的Go字段。

因此,您没有什么特别的事情要做,只需解组您必须拥有的东西,以获取您想要或可能想要的价值。

需要注意的一件事是,如果JSON文本中缺少字段,则json包将不会更改相应的Go字段,因此,如果您以“
fresh”(零)开头,则该字段将保留其零值。类型。

在大多数情况下,这足以检测字段的存在或不存在(在JSON中),例如,如果在Go
struct中您有一个SortBy类型的字段string,如果在JSON中缺少此字段,则它将保持为空string""

如果零值有用且有效,那么您可以转向使用指针。例如,如果在您的应用程序中,empty
string为有效值SortBy,则可以将该字段声明为指针:*string。并且在这种情况下,如果JSON文本中缺少nil该值,则它将保留为任何指针类型的零值。

请参阅以下示例:

type Data struct {
    I int
    S string
    P *string
}

func main() {
    var d Data
    var err error

    d, err = Data{}, nil
    err = json.Unmarshal([]byte(`{"I":1, "S":"sv", "P":"pv"}`), &d)
    fmt.Printf("%#v %v\n", d, err)

    d, err = Data{}, nil
    err = json.Unmarshal([]byte(`{"I":1}`), &d)
    fmt.Printf("%#v %v\n", d, err)

    d, err = Data{}, nil
    err = json.Unmarshal([]byte(`{"S":"abc"}`), &d)
    fmt.Printf("%#v %v\n", d, err)
}

输出(在Go Playground上尝试):

main.Data{I:1, S:"sv", P:(*string)(0x1050a150)} <nil>
main.Data{I:1, S:"", P:(*string)(nil)} <nil>
main.Data{I:0, S:"abc", P:(*string)(nil)} <nil>
2020-07-02