簡體   English   中英

更改 go 結構中字段的值

[英]Changing value of field in a go struct

我正在 golang 中向外部 api 發出 http 請求。它給出了{"error":[]string, "result":changing interface{}}的一般響應。 根據發出請求的 function,結果字段會發生變化。 因為我知道我運行的每個 function 的結果字段的結構,所以我希望能夠在解組為 json 之前更改結果的值。我嘗試使用以下代碼執行此操作:

func GetAssets(output *Resp, resultType interface{}) error {
    return publicRequest("/Assets", output, resultType)
}

func publicRequest(endPoint string, output *Resp, resultType interface{}) error {
    url := Rest_url + Pub_rest_url + endPoint //"https://api.kraken.com/0/public/Assets in this case
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    defer resp.Body.Close()

    output.Result = resultType
    return json.NewDecoder(resp.Body).Decode(&output)
}

這是它在 main 中的運行方式

type Resp struct {
    Error  []string    `json:"error"`
    Result interface{} `json:"result"`
}

type AssetInfo struct {
    Aclass   string `json:"aclass"`
    Altname  string `json:"altname"`
    Decimals int    `json:"decimals"`
    Display  int    `json:"display_decimals"`
}

func main() {
    var result map[string]AssetInfo
    jsonData := Resp{}
    rest_api_client.GetAssets(&jsonData, result)
    fmt.Println(jsonData)
}

問題是它沒有正確解組。 為每個資產創建一個 map,但每個資產中包含的數據也存儲在 map 中。我不確定我是否解釋得很好,但這是解組后的當前響應以理解我的意思。

這是 Resp.Result 的數據類型: map[string]interface {}

{[] map[1INCH:map[aclass:currency altname:1INCH decimals:10 display_decimals:5] AAVE:map[aclass:currency altname:AAVE decimals:10 display_decimals:5] ACA:map[aclass:currency altname:ACA decimals:10 display_decimals:5] ADA:map[aclass:currency altname:ADA decimals:8 display_decimals:6]...}

我正在尋找的響應類型是map[string]AssetInfo 希望它可以像這樣解組:

{[] map[1INCH:{currency 1INCH 10 5} AAVE:{currency AAVE 10 5} ACA:{currency ACA 10 5} ADA:{currency ADA 8 6} ADA.S:{currency ADA.S 8 6}...}

有什么幫助嗎? 我寧願讓 Resp 結構盡可能通用,只更改 Result 字段的值(如果這甚至可以正確執行),因為我計划有多個函數調用 api 的不同端點,它們將都具有具有不同結果類型的 Resp 結構的相同底層響應類型

您可以在以下存儲庫中查看工作示例:

https://github.com/alessiosavi/GoArbitrage/blob/e107af466852b1ed30c2413eb4401595f7412b4f/markets/kraken/kraken.go

基本上,我定義了以下結構:

type Tickers struct {
    Error  []interface{}     `json:"error"`
    Result map[string]Ticker `json:"result"`
}

type Ticker struct {
    Aclass          string `json:"aclass"`
    Altname         string `json:"altname"`
    Decimals        int    `json:"decimals"`
    DisplayDecimals int    `json:"display_decimals"`
}

比我通過以下方式執行請求:

const KRAKEN_TICKERS_URL string = `https://api.kraken.com/0/public/Assets`

type Kraken struct {
    PairsNames []string                                 `json:"pairs_name"`
    Pairs      map[string]datastructure.KrakenPair      `json:"pairs"`
    OrderBook  map[string]datastructure.KrakenOrderBook `json:"orderbook"`
    MakerFee   float64                                  `json:"maker_fee"`
    TakerFees  float64                                  `json:"taker_fee"`
    // FeePercent is delegated to save if the fee is in percent or in coin
    FeePercent bool `json:"fee_percent"`
    Tickers    []string
}


// Init is delegated to initialize the maps for the kraken
func (k *Kraken) Init() {
    k.Pairs = make(map[string]datastructure.KrakenPair)
    k.OrderBook = make(map[string]datastructure.KrakenOrderBook)
    k.SetFees()
}

// SetFees is delegated to initialize the fee type/amount for the given market
func (k *Kraken) SetFees() {
    k.MakerFee = 0.16
    k.TakerFees = 0.26
    k.FeePercent = true
}


func (k *Kraken) GetTickers() error {
    res := datastructure.Tickers{}
    var err error
    var request req.Request
    var data []byte
    var tickers []string
    resp := request.SendRequest(KRAKEN_TICKERS_URL, "GET", nil, nil, false, 10*time.Second)
    if resp.Error != nil {
        zap.S().Debugw("Error during http request. Err: " + resp.Error.Error())
        return resp.Error
    }
    if resp.StatusCode != 200 {
        zap.S().Warnw("Received a non 200 status code: " + strconv.Itoa(resp.StatusCode))
        return errors.New("NON_200_STATUS_CODE")
    }
    data = resp.Body
    if err = json.Unmarshal(data, &res); err != nil {
        zap.S().Warn("ERROR! :" + err.Error())
        return err
    }
    zap.S().Infof("Data: %v", res.Result)
    tickers = make([]string, len(res.Result))
    i := 0
    for key := range res.Result {
        tickers[i] = res.Result[key].Altname
        i++
    }
    k.Tickers = tickers
    return nil
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM