Go JSON操作

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

Go json manipulation

问题

嗨,你好!这是你的代码的翻译:

package test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

type Collection struct {
	Contract string
}

type Data struct {
	Activity Activity `json:"activity"`
}

type Activity struct {
	Activities Activities `json:"activities"`
	HasMore    bool       `json:"hasMore"`
}

type Activities []Sale

type Sale struct {
	From             string           `json:"from"`
	From_login       string           `json:"from_login"`
	To               string           `json:"to"`
	To_login         string           `json:"to_login"`
	Transaction_hash string           `json:"transaction_hash"`
	Timestamp        int              `json:"timestamp"`
	Types            string           `json:"type"`
	Price            float32          `json:"price"`
	Quantity         string           `json:"quantity"`
	Nft              Nft              `json:"nft"`
	Attributes       string           `json:"attributes"`
	Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
	Name       string        `json:"name"`
	Thumbnail  string        `json:"thumbnail"`
	Asset_id   string        `json:"asset_id"`
	Collection NftCollection `json:"collection"`
}

type NftCollection struct {
	Avatar    string `json:"avatar"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

type CollectionStruct struct {
	Avatar    string `json:"avatar"`
	Address   string `json:"address"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

func (c Collection) GetSales(filter, types string) []Sale {
	client := &http.Client{Timeout: time.Duration(1) * time.Second}

	const url = "https://backend.api.io/query"

	req, err := http.NewRequest("POST", url, nil)
	if err != nil {
		panic(err)
	}

	req.Header.Set("Content-Type", "application/json")

	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}

	defer res.Body.Close()
	content, err := ioutil.ReadAll(res.Body)
	if err != nil {
		panic(err)
	}

	var resultJson Data
	json.Unmarshal(content, &resultJson)
	fmt.Printf("%+v\n", resultJson)
	return resultJson.Activity.Activities
}

我不明白为什么我的Sale结构体是空的:/ 我创建了所有这些结构体以便使用Unmarshal进行循环。我检查了返回的JSON的结构方式,并将其复制了下来。我确定我漏掉了一些东西,但不知道是什么。

编辑:我想我找到问题了,实际上数组应该是Activities而不是Sale

type Collection struct {
	Contract string
}

type Data struct {
	Activity Activity `json:"activity"`
}

type Activity struct {
	Activities Activities `json:"activities"`
	HasMore    bool       `json:"hasMore"`
}

type Activities []struct {
	Sale Sale
}

type Sale struct {
	From             string           `json:"from"`
	From_login       string           `json:"from_login"`
	To               string           `json:"to"`
	To_login         string           `json:"to_login"`
	Transaction_hash string           `json:"transaction_hash"`
	Timestamp        int              `json:"timestamp"`
	Types            string           `json:"type"`
	Price            float32          `json:"price"`
	Quantity         string           `json:"quantity"`
	Nft              Nft              `json:"nft"`
	Attributes       string           `json:"attributes"`
	Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
	Name       string        `json:"name"`
	Thumbnail  string        `json:"thumbnail"`
	Asset_id   string        `json:"asset_id"`
	Collection NftCollection `json:"collection"`
}

type NftCollection struct {
	Avatar    string `json:"avatar"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

type CollectionStruct struct {
	Avatar    string `json:"avatar"`
	Address   string `json:"address"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

但这次它返回了这个:{Activity:{Activities:[] HasMore:false}},其中Activities的值应该是一个Nft结构体的数组。

英文:

Hey there just started to transform my python code to Go, but have some issue on the json manipulations... here is my code so far

package test

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

type Collection struct {
	Contract string
}

type Data struct {
	Activity Activity `json:"activity"`
}

type Activity struct {
	Activities Activities `json:"activities"`
	HasMore    bool       `json:"hasMore"`
}

type Activities []Sale

type Sale struct {
	From             string           `json:"from"`
	From_login       string           `json:"from_login"`
	To               string           `json:"to"`
	To_login         string           `json:"to_login"`
	Transaction_hash string           `json:"transaction_hash"`
	Timestamp        int              `json:"timestamp"`
	Types            string           `json:"type"`
	Price            float32          `json:"price"`
	Quantity         string           `json:"quantity"`
	Nft              Nft              `json:"nft"`
	Attributes       string           `json:"attributes"`
	Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
	Name       string        `json:"name"`
	Thumbnail  string        `json:"thumbnail"`
	Asset_id   string        `json:"asset_id"`
	Collection NftCollection `json:"collection"`
}

type NftCollection struct {
	Avatar    string `json:"avatar"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

type CollectionStruct struct {
	Avatar    string `json:"avatar"`
	Address   string `json:"address"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

func (c Collection) GetSales(filter, types string) []Sale { // déclaration de ma méthode GetSales() liée à ma structure Collection
	client := &http.Client{Timeout: time.Duration(1) * time.Second}

	const url = "https://backend.api.io/query"

	// create a new request using http
	req, err := http.NewRequest("POST", url)
	if err != nil {
		panic(err)
	}

	// set header for the request
	req.Header.Set("Content-Type", "application/json")

	// send request
	res, err := client.Do(req)
	if err != nil {
		panic(err)
	}

	defer res.Body.Close()
	content, err_ := ioutil.ReadAll(res.Body)
	if err_ != nil {
		panic(err_)
	}

	var resultJson Data
	json.Unmarshal(content, &resultJson)
	fmt.Printf("%+v\n", resultJson)
	return resultJson.Activity.Activities.Sale

}

i don't understand why my Sale structure is empty :/ I created all of these structures in order to use Unmarshal so i can loop. I check the way the returned json is structured and copied it i'm sure i missed something but don't know what

EDIT: I think that i have something, actually the array is Activities and not Sale :

type Collection struct {
	Contract string
}

type Data struct {
	Activity Activity `json:"activity"`
}

type Activity struct {
	Activities Activities `json:"activities"`
	HasMore    bool       `json:"hasMore"`
}

type Activities []struct {
	Sale Sale //`json:"sale"`
}

type Sale struct {
	From             string           `json:"from"`
	From_login       string           `json:"from_login"`
	To               string           `json:"to"`
	To_login         string           `json:"to_login"`
	Transaction_hash string           `json:"transaction_hash"`
	Timestamp        int              `json:"timestamp"`
	Types            string           `json:"type"`
	Price            float32          `json:"price"`
	Quantity         string           `json:"quantity"`
	Nft              Nft              `json:"nft"`
	Attributes       string           `json:"attributes"`
	Collection       CollectionStruct `json:"collection"`
}

type Nft struct {
	Name       string        `json:"name"`
	Thumbnail  string        `json:"thumbnail"`
	Asset_id   string        `json:"asset_id"`
	Collection NftCollection `json:"collection"`
}

type NftCollection struct {
	Avatar    string `json:"avatar"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

type CollectionStruct struct {
	Avatar    string `json:"avatar"`
	Address   string `json:"address"`
	Name      string `json:"name"`
	Certified bool   `json:"certified"`
}

But this time it returns me this : {Activity:{Activities:[] HasMore:false}} where Activities value should be an array of Nft struct

答案1

得分: 0

你的代码无法编译(由于存在一些未定义的变量),所以很难区分功能问题和语法问题。

然而,有一点很明显:你使用 req, err := http.NewRequest(...) 创建了一个HTTP请求,但是你没有使用客户端来执行该请求。可以参考文档中的示例:

client := &http.Client{
	CheckRedirect: redirectPolicyFunc,
}

resp, err := client.Get("http://example.com")
// ...

req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

如果你使用 NewRequest 创建请求,你必须使用 client.Do(req) 来执行它。

英文:

Your code as written won't compile (due to a couple of undefined variables), so it's hard to separate functional problems from syntactic problems.

However, one thing stands out: You're creating an HTTP request with req, err := http.NewRequest(...), but you're never executing the request with a client. See e.g. the documentation, which includes this example:

client := &http.Client{
CheckRedirect: redirectPolicyFunc,
}
resp, err := client.Get("http://example.com")
// ...
req, err := http.NewRequest("GET", "http://example.com", nil)
// ...
req.Header.Add("If-None-Match", `W/"wyzzy"`)
resp, err := client.Do(req)
// ...

If you use NewRequest to create a request, you must use client.Do(req) to execute it.

答案2

得分: 0

根据@larsks的回答,我看到了更多的错误:

  1. ioutil.ReadAll已经返回了一个字节数组,你可以直接用它来进行解组。json.Unmarshal(content, &resultJson)

  2. 许多错误被忽略了,所以如果遇到任何错误,执行不会停止。

我建议将函数改为以下形式:

func (c Collection) GetSales(filter, types string) []Sale {
    const url = "https://api.com/"

    req, err := http.NewRequest("POST", url, requestBody)
    if err != nil {
        panic(err)
    }
    
    res, err := http.DefaultClient.Do(req)
    if err != nil {
        panic(err)
    }

    defer res.Body.Close()
    content, err := ioutil.ReadAll(res.Body)
    if err != nil {
        panic(err)
    }

    var resultJson Data
    err = json.Unmarshal(content, &resultJson)
    if err != nil {
        panic(err)
    }

    fmt.Printf("%+v\n", resultJson)
    return resultJson.Activity.Activities.Sales
}
英文:

Adding to @larsks 's answer, there are more errors that I can see

  1. ioutil.ReadAll already returns a byte array which you can directly use for un-marshalling. json.Unmarshal(content, &resultJson)

  2. Many errors are ignored so execution won't stop if any error is encountered.

I suggest changing the function as follows:

func (c Collection) GetSales(filter, types string) []Sale {
const url = "https://api.com/"
req, err := http.NewRequest("POST", url, requestBody)
if err != nil {
panic(err)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
content, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
var resultJson Data
err = json.Unmarshal(content, &resultJson)
if err != nil {
panic(err)
}
fmt.Printf("%+v\n", resultJson)
return resultJson.Activity.Activities.Sales
}

huangapple
  • 本文由 发表于 2022年8月28日 06:31:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/73514820.html
匿名

发表评论

匿名网友

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

确定