将json null解组为NullString的指针

时间:2018-10-01 17:56:20

标签: json go unmarshalling

我无法将空值json.Unmarshal插入结构中的*NullString字段中。这是我的意思的简化示例:

package main

import (
  "database/sql"
  "encoding/json"
  "log"
)

// NullString
type NullString struct {
  sql.NullString
}

func (n *NullString) UnmarshalJSON(b []byte) error {

  n.Valid = string(b) != "null"
  e := json.Unmarshal(b, &n.String)
  return e
}

type Person struct {
  Name *NullString `json:"name"`
}

func BuildUpdateSQL(jsonString string) string {

  p := Person{}
  e := json.Unmarshal([]byte(jsonString),&p)
  if e != nil {
    log.Println(e)
  }

  if p.Name != nil {
    log.Println(p,p.Name)
  } else {
    log.Println(p)
  }
  return ""
}
func main() {
  // Correctly leaves p.Name unset
  BuildUpdateSQL(`{"field_not_exist":"samantha"}`)

  // Correctly sets p.Name
  BuildUpdateSQL(`{"name":"samantha"}`)

  // Incorrectly leaves p.Name as nil when I really want p.Name to have a NullString with .Valid == false
  BuildUpdateSQL(`{"name":null}`)
}

如您所见,解组适用于非null的json值。但是当我传入一个空的json值时,NullString解组器似乎甚至没有触发。

有人知道我在做什么错吗?

背景

之所以尝试这样做是因为我计划从REST API获取JSON值。并非API中的所有字段都是必填字段。因此,我将指针用于结构字段来帮助我构建SQL Update语句,因为:

  • 字段为nil表示未填充(不包含SET name = ?
  • 非空NullString.Valid == false表示实际的空值(包括SET name = NULL
  • 和非null NullString.Valid == true表示存在真实的字符串值(包括SET name = ?

1 个答案:

答案 0 :(得分:2)

是的,这是因为以下解编规则:

  

要将JSON解组为指针,Unmarshal首先处理JSON为JSON文字为null的情况。在这种情况下,Unmarshal会将指针设置为nil。否则,Unmarshal会将JSON解组为指针所指向的值。

Documentation for encoding/json)。

我建议要做的是添加一个Set字段,当解散UnmarshalJSON时将其更改为true(如果有任何值,则保证将其解雇),然后更改{{1 }}转换为简单的*NullString,如下所示:

NullString

Playground