gpt4 book ai didi

由 reflect.New() 制作的 slice 的 JSON 编码在 golang 中给出 null

转载 作者:IT王子 更新时间:2023-10-29 00:54:54 26 4
gpt4 key购买 nike

我在 golang 中使用 reflect 来制作一个新的初始化 slice 。但是当我 json.Marshal 这个新的反射 slice 时,我得到一个 JSON null 值而不是 []。请在此处查看我比较两种情况的示例:

package main

import (
"encoding/json"
"reflect"
"log"
)
func makeslice(slice interface{}) interface{} {

return reflect.New(reflect.TypeOf(slice)).Elem().Interface()
}
func main() {

s0 := []int{2,3,5}

s1 := makeslice(s0).([]int)
js1,e1 := json.Marshal(s1)
log.Println("case 1:",reflect.TypeOf(s1),reflect.ValueOf(s1),e1,string(js1))

s2 := []int{}
js2,e2 := json.Marshal(s2)
log.Println("case 2:",reflect.TypeOf(s2),reflect.ValueOf(s2),e2,string(js2))

}

这给出了输出:

case 1: []int [] <nil> null
case 2: []int [] <nil> []

注意 case 1case 2 产生完全相同的日志输出,除了最终的 json 字符串,第一个 case 显示 null第二种情况显示 []

为什么会这样?我想要的是让 case 1 显示 [] 因为我 friend 的客户端应用程序总是需要一个数组,零长度数组不应显示为 null .

我做错了什么?

最佳答案

reflect.New() 根据 documentation 做了什么:

New returns a Value representing a pointer to a new zero value for the specified type. That is, the returned Value's Type is PtrTo(typ).

在您的代码中,s0s2 都不为零。但是s1将是[]int类型的零值指针,即nil;因为变量是使用 reflect.New() 创建的。

下面的代码证明 slice 零值是nil

var a []int = []int{}
log.Printf("%#v \n", a) // ====> []int{}

var b []int
log.Printf("%#v \n", b) // ====> []int(nil)

我建议使用 reflect.MakeSlice() 来制作 slice 。生成的值不会是 nil

func makeslice(slice interface{}) interface{} {
return reflect.MakeSlice(reflect.TypeOf(slice), 0, 0).Interface()
}

然后根据您的代码,输出将是:

case 1: []int [] <nil> []
case 2: []int [] <nil> []

工作 field :https://play.golang.org/p/tL3kFqVwOtC


将具有nil 值的[]int 转换为JSON 将得到null。但是将 []int{} 数据转换为 JSON 将得到 [],因为数据是空 slice (不是 nil slice )。


作为评论的后续,此方法生成一个可寻址的 slice ,可以使用反射进一步修改:

func makeslice(slice interface{}) interface{} {
newsliceval := reflect.MakeSlice(reflect.TypeOf(slice),0,0)
newslice := reflect.New(newsliceval.Type()).Elem()
newslice.Set(newsliceval)

/*
* make any desired changes to newslice with reflect package
*/

return newslice.Interface()
}

这里有更多解释 Why golang reflect.MakeSlice returns un-addressable Value .

关于由 reflect.New() 制作的 slice 的 JSON 编码在 golang 中给出 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53097018/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com