如何在Go中打印出一个JSON

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

How to print out a JSON in Go

问题

我是新手Go语言,我在弄清楚如何打印出我创建的JSON时遇到了麻烦。我正在使用"encoding/json",并且得到了一个[]byte返回。但是当我尝试打印出来时,我得到了以下错误信息:

cannot use json_msg (type []byte) as type string in function argument

在收到这个错误后,我尝试将[]byte数组转换为字符串或空接口。但是我似乎无法让它工作。有什么想法吗?相关的代码如下:

type Message struct {
    Id int
    Name string
}

for _, row := range rows {
    m := Message{row.Int(0), row.Str(1)}

    json_msg, err := json.Marshal(m)

    if err == nil {
        panic(err)
    }//if

    //尝试下面的代码打印一个接口,也不起作用
    //var f interface{}
    //err = json.Unmarshal(json_msg, &f)

    fmt.Fprintf(c.ResponseWriter, json_msg)
}//for
英文:

I'm new to Go, and having trouble figuring out how to print out a JSON I've created. I'm using "encoding/json" and am getting a []byte returned. However when I go to print this out I get:

cannot use json_msg (type []byte) as type string in function argument

After receiving this I've tried to convert the []byte array to a string or an empty interface. However I can't seem to get it to work. Any ideas? Relevant code below:

type Message struct {
	Id int
	Name string
}



for _, row := range rows {
	m := Message{row.Int(0), row.Str(1)}

	json_msg, err := json.Marshal(m)

	if err == nil {
		panic(err)
	}//if

            //tried below to print out a interface, didn't work either
	//var f interface{}
	//err = json.Unmarshal(json_msg, &f)

	fmt.Fprintf(c.ResponseWriter, json_msg)
}//for

答案1

得分: 15

有几种方法可以获得你想要的结果。

首先,直接回答你的问题,fmt.Fprintf 的类型是 func(io.Writer, string, ...interface{})。由于你将 c.ResponseWriter 传递给它,我假设它是满足 io.Writer 的东西。fmt.Fprintf 的第二个参数是一个格式化字符串。如果你想将某个东西打印为字符串,你可以使用 %s 格式化字符串,所以你需要的是这样的:

fmt.Fprintf(c.ResponseWriter, "%s", json_msg)

这直接回答了你的问题,但是让我们再深入一点:这是解决你所面临问题的正确方式吗?实际上不是,这种方式有点奇怪。

首先,因为我们知道 fmt.Fprintf 接受 io.Writer,我们正在讨论的是一个具有 Write([]byte) (int, error) 方法的东西。你可以通过直接在 ResponseWriter 上调用 Write() 方法将 []byte 数据写入 ResponseWriter

_, err := c.ResponseWriter.Write(json_msg)

这样稍微不那么笨拙。事实证明,有一种更好的方法来做到这一点:使用 json.Encoderjson.Encoder 是一个结构体,嵌入了一个 io.Writer,实际上为任何 io.Writer 结构体添加了一个 Encode 方法,该方法将结构体编码为 JSON 并将其写入写入器。不同之处在于,你所做的是将数据编码为内存中的字节切片,然后将其复制到 io.Writer 中,而你可以直接写入,就像这样:

err := json.NewEncoder(c.ResponseWriter).Encode(m)

现在你甚至没有中间的 []byte 格式了。

英文:

there's a handful of ways to get what you're looking for.

First, to answer your question directly, fmt.Fprintf if of type func(io.Writer, string, ...interface{}). Since you're passing c.ResponseWriter into it, I assume that's something that satisfies io.Writer. The second argument to fmt.Fprintf is a format string. If you want to print something as a string, you use the %s format string, so what you would want is this:

fmt.Fprintf(c.ResponseWriter, "%s", json_msg)

that answers your question directly, but let's go a little further: is that the right way to solve the problem you're solving? No, not really; it's a little weird to do it that way.

First off, because we know that fmt.Fprintf accepts io.Writer, we're talking about something with a method of the form Write([]byte) (int, error). You could just write that []byte data to the ResponseWriter by calling the Write() method on the ResponseWriter directly:

_, err := c.ResponseWriter.Write(json_msg)

that's slightly less awkward. It turns out, there's an even better way to do this: use a json.Encoder. A json.Encoder is a struct that embeds an io.Writer, effectively adding to any io.Writer struct an Encode method, which will encode structs to json and write them to the writer. The difference is that what you're doing encodes the data to a byte slice in memory, and then copies that into an io.Writer, when you could just write it directly, like this:

err := json.NewEncoder(c.ResponseWriter).Encode(m)

and now you don't even have that intermediate []byte format.

答案2

得分: 2

你在一个Printf类型的函数中使用json_msg作为格式字符串,但是该函数只接受string作为格式字符串([]bytestring是不同的类型,尽管你可以将它们互相转换)。正确的写法是指定格式字符串:

fmt.Fprintf(WRITER_OBJ, "%s", json_msg)

这将打印[]byte作为它的Unicode内容。在Fprintf/Printf中不应该使用变量作为格式字符串。我不认为这会像在C中那样成为一个问题,但如果一个%<something>出现在你的JSON中可能会引起问题。

英文:

You are using json_msg as the format string in a Printf type function, which only excepts string as the format string ([]byte and string are distinct types. Although you can cast them to each other). The proper way of writing a byte slice would be to specify the format string:

fmt.Fprintf(WRITER_OBJ, &quot;%s&quot;, json_msg)

This will print the []byte as it's Unicode contents. You shouldn't use varibles as the format string in Fprintf/Printf. I don't think it's a problematic as it would be in C. But it might cause issues if a "%<something>" got in your JSON.

答案3

得分: 1

fmt.Fprintf(c.ResponseWriter, string(json_msg))

英文:
fmt.Fprintf(c.ResponseWriter, string(json_msg))

Would be correct way to cast your []byte to a string

huangapple
  • 本文由 发表于 2013年1月29日 01:08:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/14567324.html
匿名

发表评论

匿名网友

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

确定