为什么在代码中将空数组进行 JSON 编码会返回 null 呢?

huangapple go评论108阅读模式
英文:

Why does json encoding an empty array in code return null?

问题

所以我有一个类似这样的类型:

type TextTagRelationship struct {
  Id int64 `json:"id"`
  TagId int64 `json:"tag_id"`
  TaggedText string `json:"tagged_text"`
  TagName string `json:"tag_name"`
  PageNumber int64 `json:"page_number"`
  Color string `json:"color"`
}

type TextTagRelationships []TextTagRelationship

现在,我有一个处理程序,做了这样的事情:

func getTaggedTextForPage(w http.ResponseWriter, r *http.Request) {
    vars := mux.Vars(r)
    pageNumber, err := strconv.ParseInt(vars["pageNumber"], 10, 64)
    check(err)
    defer r.Body.Close()
    rows, err := db.Query("SELECT * from tagged_text WHERE page_number = ?", pageNumber)
    check(err)
    var textTagRelationships []TextTagRelationship
    var textTagRelationship TextTagRelationship
    for rows.Next() {
        // 在这里执行 SQL 代码
        textTagRelationships = append(textTagRelationships, textTagRelationship)
    }
    

    if err := json.NewEncoder(w).Encode(textTagRelationships); err != nil {
        check(err)
    }
}

如果有实际的行,这个工作正常。但是,当在响应中编码一个空数组 textTagRelationships 时,在 Chrome 控制台中我得到一个 null。为什么会这样?看起来 textTagRelationships 实际上是一个 [],所以我本来期望编码为 [],并且我的响应有一个 []

英文:

So I have a types like this

type TextTagRelationship struct {
  Id int64 `json:"id"`
  TagId int64 `json:"tag_id"`
  TaggedText string `json:"tagged_text"`
  TagName string `json:"tag_name"`
  PageNumber int64 `json:"page_number"`
  Color string `json:"color"`
}

type TextTagRelationships []TextTagRelationship

Now, I have a handler that does something like this

func getTaggedTextForPage(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	pageNumber, err := strconv.ParseInt(vars["pageNumber"], 10, 64)
	check(err)
	defer r.Body.Close()
	rows, err := db.Query("SELECT * from tagged_text WHERE page_number = ?", pageNumber)
	check(err)
	var textTagRelationships []TextTagRelationship
	var textTagRelationship TextTagRelationship
	for rows.Next() {
        //execute sql code here
		textTagRelationships = append(textTagRelationships, textTagRelationship)
	}
	

	if err := json.NewEncoder(w).Encode(textTagRelationships); err != nil {
		check(err)
	}
}

This works fine if there are actual rows, but when encoding an empty array textTagRelationships, in my response in the chrome console I get a null. Why is this happening? It looks like textTagRelationships is actually a [] and so I would have expected the encoding to encode a [] and my response to have a [].

答案1

得分: 12

这似乎是Go语言中的一个陷阱。

https://danott.co/posts/json-marshalling-empty-slices-to-empty-arrays-in-go.html

解决这个问题的方法是不依赖于默认的初始化行为,而是使用make函数。

var textTagRelationships TextTagRelationships = make(TextTagRelationships, 0)

英文:

It looks like this is a gotcha in Go.

https://danott.co/posts/json-marshalling-empty-slices-to-empty-arrays-in-go.html

The solution around this is to not rely on the default init behaviour and actually do a make.

var textTagRelationships TextTagRelationships = make(TextTagRelationships, 0)

huangapple
  • 本文由 发表于 2017年5月23日 02:30:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/44119793.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定