英文:
How do I create this this JSON object?
问题
{
"query": {
"query_string": {
"query": "
}
}
}
我正在使用的API要求我以这种格式发送查询。我一直在尝试使用map创建这个格式,但是我一直遇到错误,并且没有找到任何在线解决方案。
编辑:我找到了一种方法,但是否有更好的方法?
test := map[string]map[string]map[string]string {
"query": map[string]map[string]string {
"query_string": map[string]string{
"query": query,
},
},
}
英文:
{
"query": {
"query_string": {
"query": "<query string>"
}
}
}
The API I'm using requires that I send my queries in this format. I've been trying to find a way to to create this using maps but I keep getting errors and haven't been able to find any solutions online.
Edit: I found a way to do it, is there a better way?
test := map[string]map[string]map[string]string {
"query": map[string]map[string]string {
"query_string": map[string]string{
"query": query,
},
},
}
答案1
得分: 4
在Go语言中,你可以将数据解组成多种不同的结构体。其中最模糊的是interface{}
。不过我建议不要使用它,因为这样你就无法获得真正的类型安全性。另一个极端是使用结构体,对于你的示例JSON,结构体应该如下所示:
type Wrapper struct {
Query Query `json:"query"`
}
type Query struct {
QueryString QueryString `json:"query_string"`
}
type QueryString struct {
Query string `json:"query"`
}
在中间的某个位置,根据你的示例JSON,可以使用map[string]map[string]map[string]
。如果你不知道如何使用encoding/json
包,请查看这里的示例:https://golang.org/pkg/encoding/json/#example_Unmarshal
这很简单,如果你的输入是[]byte
类型,然后你实例化你想要解组成的类型,你只需要调用json.Unmarshal(jsonBytes, &ThingToUnmarshalInto)
即可。
编辑:根据hobbs的评论,看起来你实际上是想要生成那个JSON字符串并发送给服务器。在这种情况下,请使用上面提供的结构体。其他答案中提供的示例演示了你所需的一切。几乎和我上面描述的一样,只是你要使用json.Marshal
,将你想要转换为JSON字符串的实例作为参数,而不是将JSON字符串作为[]byte
传递给unmarshal
来获取一个结构体。我错误地认为你是在接收那个JSON字符串,而不是试图生成它。
英文:
In Go you can unmarshal into a variety of different structures. The most ambiguous being an interface{}
. I recommend against that though as you forgo the opportunity to have any real type safety. The other extreme is to use structs, for your example json they would look like this;
type Wrapper struct {
Query Query `json:"query"`
}
type Query struct {
QueryString QueryString `json:"query_string"`
}
type QueryString struct {
Query string `json:"query"`
}
Something in the middle, given you example json would be a map[string]map[string]map[string]
. Check out the example here if you don't know how to make use of the encoding/json
package. https://golang.org/pkg/encoding/json/#example_Unmarshal
It's pretty straight forward, if you have your input in a []byte
and then you instantiate the type you want to unmarshal it into you can just call json.Unmarhsal(jsonBytes, &ThingToUnmarshalInto)
EDIT: based on hobbs' comment it appears you're actually trying to make that json to send to the server. In which case, use the structs above. The example supplied in the other answer demonstrates everything you need. Everything is pretty much the same as I described above except you're calling json.Marshal
with an instance of what you want to be turned in to a json string, rather than taking the json string as a []byte
and passing it into unmarshal to get a struct. I mistakenly thought you were receiving that json, not trying to form it.
答案2
得分: 3
这是一个使用 map 方式和 struct 方式的示例,你可以在 Play 上看到。
如你所见,使用 map 的形式通常代码更少,如果你需要发送一次性请求,这种方式更加清晰。
如果请求中有很多嵌套或共享类型,使用 struct 的形式可能更高效,也更加清晰。如果你最终选择使用 struct,你可能会想要使用类似于 evanmcdonnal 的答案中的结构。这里为了简洁起见,我使用了匿名结构体。
package main
import "encoding/json"
import "log"
type M map[string]interface{}
type Query struct {
Query struct {
QueryString struct {
Query string `json:"query"`
} `json:"query_string"`
} `json:"query"`
}
func main() {
b, err := json.Marshal(M{"query": M{"query_string": M{"query": "query goes here"}}})
if err != nil {
log.Fatalln(err)
}
log.Println(" As Map:", string(b))
var q Query
q.Query.QueryString.Query = "query in a struct"
b, err = json.Marshal(q)
if err != nil {
log.Fatalln(err)
}
log.Println("As Struct:", string(b))
}
英文:
Here's an example on Play using both the map way and the struct way.
As you can see, the map form is less code in general and more clear if you need to send one off requests like this.
Struct form will tend to be more performant and possibly more clear if there are a lot of nested or shared types in your requests. If you end up going the struct route, you would likely want something that resembles evanmcdonnal's answer. I used anonymous structs here for brevity.
package main
import "encoding/json"
import "log"
type M map[string]interface{}
type Query struct {
Query struct {
QueryString struct {
Query string `json:"query"`
} `json:"query_string"`
} `json:"query"`
}
func main() {
b, err := json.Marshal(M{"query": M{"query_string": M{"query": "query goes here"}}})
if err != nil {
log.Fatalln(err)
}
log.Println(" As Map:", string(b))
var q Query
q.Query.QueryString.Query = "query in a struct"
b, err = json.Marshal(q)
if err != nil {
log.Fatalln(err)
}
log.Println("As Struct:", string(b))
}
答案3
得分: 1
Anonymous Struct
是Go语言中的一个很好的特性。这是一个等价的Go struct
,用于通过encoding/json包进行编组/解组的JSON
:
type MyType struct {
Query struct {
QueryString struct {
Query string `json:"query"`
} `json:"query_string"`
} `json:"query"`
}
是的,你也可以只使用一个有类型的变量,而不引入新的类型(如果在你的情况下适用的话):
var myVar struct {
Query struct {
QueryString struct {
Query string `json:"query"`
} `json:"query_string"`
} `json:"query"`
}
英文:
Anonymous Struct
is one of nice features of Go. This is an equivalent Go struct
for your JSON
to get marshaled/unmarshaled to/from using encoding/json package:
type MyType struct {
Query struct {
QueryString struct {
Query string `json:"query"`
} `json:"query_string"`
} `json:"query"`
}
And yes, you could just use a typed variable without introducing a new type (if this is proper to use in your case):
var myVar struct {
Query struct {
QueryString struct {
Query string `json:"query"`
} `json:"query_string"`
} `json:"query"`
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论