为了账号安全,请及时绑定邮箱和手机立即绑定

json:无法将数组解组为结构类型的 Go 值

json:无法将数组解组为结构类型的 Go 值

Go
智慧大石 2022-05-05 16:01:15
我正在构建一个从伦敦地铁 API 读取信息的应用程序。我正在努力将 GET 请求解析为可读的内容,并且用户可以在其中访问特定的行信息。这是我当前的代码,我正在使用一个结构来存储解组后来自 GET 请求的响应。// struct for decoding into a structure    var tubeStatuses struct {        object []struct {            typeDef      []string `json:"$type"`            idName       string   `json:"id"`            name         string   `json:"name"`            modeName     string   `json:"modeName"`            disruptions  string   `json:"disruption"`            created      string   `json:"created"`            modified     string   `json:"modified"`            statusObject []struct {                zeroObject []struct {                    typeDef        string `json:"$type"`                    id             int    `json:"id"`                    statusSeverity int    `json:"statusSeverity"`                    statusDesc     string `json:"statusSeverityDescription"`                    created        string `json:"created"`                    validity       string `json:"validityPeriods"`                }            }            route         string `json:"routeSections"`            serviceObject []struct {                zeroObject []struct {                    typeDef string `json:"$type"`                    name    string `json:"name"`                    uri     string `json:"uri"`                }            }            crowdingObject []struct {                typeDef string `json:"$type"`            }        }    }    fmt.Println("Now retrieving Underground line status, please wait...")    // two variables (response and error) which stores the response from e GET request    getRequest, err := http.Get("https://api.tfl.gov.uk/line/mode/tube/status")    fmt.Println("The status code is", getRequest.StatusCode, http.StatusText(getRequest.StatusCode))    if err != nil {        fmt.Println("Error!")        fmt.Println(err)    }数组解组为可读的内容?
查看完整描述

2 回答

?
www说

TA贡献1775条经验 获得超8个赞

以下是您的代码的工作版本。但是,您需要解决多个问题。

  1. 正如本线程其他地方所提到的,您应该将 TubeStatuses(注意大写)设置为一个类型和一个数组。字段名称也应大写,以便导出。

  2. 您没有考虑所有输出,并且在某些情况下类型错误。例如,您缺少一个名为“Disruption”的对象。我已经在我的示例中添加了它。“拥挤”声明的类型错误。此外,“route”又名“routeSections”不是字符串。这是另一个数组,可能是对象,但 API 没有输出让我确定 routeSections 实际包含的内容。因此,作为一种解决方法,我将其声明为“json.RawMessage”的一种类型,以允许将其解组为字节片。有关更多详细信息,请参见:https ://golang.org/pkg/encoding/json/#RawMessage

  3. 你不能使用json: "$type"`. 具体来说,不允许使用美元符号。

package main


import (

    "encoding/json"

    "fmt"

    "io/ioutil"

    "net/http"

)


type TubeStatuses struct {

    TypeDef      []string `json:"type"`

    IDName       string   `json:"id"`

    Name         string   `json:"name"`

    ModeName     string   `json:"modeName"`

    Disruptions  string   `json:"disruption"`

    Created      string   `json:"created"`

    Modified     string   `json:"modified"`

    LineStatuses []struct {

        Status []struct {

            TypeDef                   string `json:"type"`

            ID                        int    `json:"id"`

            StatusSeverity            int    `json:"statusSeverity"`

            StatusSeverityDescription string `json:"statusSeverityDescription"`

            Created                   string `json:"created"`

            ValidityPeriods           []struct {

                Period struct {

                    TypeDef  string `json: "type"`

                    FromDate string `json: "fromDate"`

                    ToDate   string `json: "toDate"`

                    IsNow    bool   `json: "isNow"`

                }

            }

            Disruption struct {

                TypeDef             string   `json: "type"`

                Category            string   `json: "category"`

                CategoryDescription string   `json: "categoryDescription"`

                Description         string   `json: "description"`

                AdditionalInfo      string   `json: "additionalInfo"`

                Created             string   `json: "created"`

                AffectedRoutes      []string `json: "affectedRoutes"`

                AffectedStops       []string `json: "affectedStops"`

                ClosureText         string   `json: closureText"`

            }

        }

    }

    RouteSections json.RawMessage `json: "routeSections"`

    ServiceTypes  []struct {

        Service []struct {

            TypeDef string `json:"type"`

            Name    string `json:"name"`

            URI     string `json:"uri"`

        }

    }

    Crowding struct {

        TypeDef string `json:"type"`

    }

}


func main() {

    fmt.Println("Now retrieving Underground line status, please wait...")


    // two variables (response and error) which stores the response from e GET request

    getRequest, err := http.Get("https://api.tfl.gov.uk/line/mode/tube/status")

    if err != nil {

        fmt.Println("Error!")

        fmt.Println(err)

    }


    fmt.Println("The status code is", getRequest.StatusCode, http.StatusText(getRequest.StatusCode))


    //close - this will be done at the end of the function

    // it's important to close the connection - we don't want the connection to leak

    defer getRequest.Body.Close()


    // read the body of the GET request

    rawData, err := ioutil.ReadAll(getRequest.Body)


    if err != nil {

        fmt.Println("Error!")

        fmt.Println(err)

    }

    ts := []TubeStatuses{}


    jsonErr := json.Unmarshal(rawData, &ts)


    if jsonErr != nil {

        fmt.Println(jsonErr)

    }


    //test

    fmt.Println(ts[0].Name)


    fmt.Println("Welcome to the TfL Underground checker!\nPlease enter a number for the line you want to check!\n0 - Bakerloo\n1 - central\n2 - circle\n3 - district\n4 - hammersmith & City\n5 - jubilee\n6 - metropolitan\n7 - northern\n8 - piccadilly\n9 - victoria\n10 - waterloo & city")

}

输出...

//img1.sycdn.imooc.com//627384770001dd9504110297.jpg

查看完整回答
反对 回复 2022-05-05
?
心有法竹

TA贡献1866条经验 获得超5个赞

您需要该结构的数组:

var tubeStatuses []struct  {...}

此外,您的结构成员名称不会被导出,因此即使在您执行此操作后它们也不会被解组。大写名称。

您的结构很大,因此请考虑将其设为类型。


查看完整回答
反对 回复 2022-05-05
  • 2 回答
  • 0 关注
  • 162 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信