使用Go中的结构数组索引超出范围

时间:2014-03-15 22:07:14

标签: go

我是Go的新手,所以我希望我能够清楚地知道这个问题。我的问题是我试图迭代一组结构但我一直遇到index out of range问题。出于这个问题的目的,我已经验证我的数组不是空的,但实际上它确实包含至少一个Services结构,而file_content是包含我的有效JSON的字符串。 }

以下代码片段代表了我遇到的问题:

type service_config struct {
    Services []struct {
        Name    string
        Command string
        Request map[string]interface{}
    }
}

var ServiceConf = service_config{}

err_json := json.Unmarshal(file_content, &ServiceConf)

for _, s := range ServiceConf.Services {
  log.Println(s)
}

所以每次运行我的代码时我都会得到:

2014/03/14 18:19:53 http: panic serving [::1]:65448: runtime error: index out of range

{
  "services" : [
    {
      "name": "translation",
      "command": "to german",
      "request": {
        "key": "XXX",
        "url": "https://www.googleapis.com/language/translate/v2?"
      }
    }
  ]
}

如果您对完整的源文件感兴趣:

    package main

import (
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "net/url"
    "os"
)

type SlackResponse struct {
    token        string
    team_id      string
    channel_id   string
    channel_name string
    timestamp    string
    user_id      string
    user_name    string
    text         string
}

type service_config struct {
    Services []struct {
        Name    string
        Command string
        Request map[string]interface{}
    }
}

var ServiceConf = service_config{}

func main() {

    content, err_read := ioutil.ReadFile("config.ini")

    if err_read != nil {
        log.Println("Could not read config")
        return
    }

    log.Println(string(content))

    err_json := json.Unmarshal(content, &ServiceConf)

    if err_json != nil {
        log.Println(err_json)
    }

    http.HandleFunc("/", handler)
    http.ListenAndServe(":"+os.Getenv("PORT"), nil)
}

func handler(w http.ResponseWriter, r *http.Request) {
    slack_response := SlackResponse{
        r.FormValue("token"),
        r.FormValue("team_id"),
        r.FormValue("channel_id"),
        r.FormValue("channel_name"),
        r.FormValue("timestamp"),
        r.FormValue("user_id"),
        r.FormValue("user_name"),
        r.FormValue("text"),
    }

    // log.Println(ServiceConf.Services[0].Request["key"])

    // loop through services to find command phrases
    for _, s := range ServiceConf.Services {
        log.Println(s)
    }

    if slack_response.user_name == "slackbot" {
        return
    }

    // fmt.Fprintf(w, "{ \"text\": \"Master %s!  You said: '%s'\" }", slack_response.user_name, slack_response.text)

    content, err := getContent("https://www.googleapis.com/language/translate/v2?key=&source=en&target=de&q=" + url.QueryEscape(slack_response.text))
    if err != nil {
        fmt.Fprintf(w, "{ \"text\": \"Huh?!\" }")
    } else {

        type trans struct {
            Data struct {
                Translations []struct {
                    TranslatedText string `json:"translatedText"`
                } `json:"translations"`
            } `json:"data"`
        }

        f := trans{}
        err := json.Unmarshal(content, &f)

        if err != nil {
            log.Println(err)
        }

        fmt.Fprintf(w, "{ \"text\": \"Translated to German you said: '%s'\" }", f.Data.Translations[0].TranslatedText)
    }
}

// array of bytes if retrieved successfully.
func getContent(url string) ([]byte, error) {
    // Build the request
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        return nil, err
    }
    // Send the request via a client
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        return nil, err
    }
    // Defer the closing of the body
    defer resp.Body.Close()
    // Read the content into a byte array
    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return nil, err
    }
    // At this point we're done - simply return the bytes
    return body, nil
}

这是堆栈跟踪:

2014/03/21 23:21:29 http: panic serving [::1]:59508: runtime error: index out of range
goroutine 3 [running]:
net/http.func·009()
    /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1093 +0xae
runtime.panic(0x215f80, 0x4b6537)
    /usr/local/Cellar/go/1.2/libexec/src/pkg/runtime/panic.c:248 +0x106
main.handler(0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
    /Users/et/src/go/src/github.com/etdebruin/gojacques/main.go:100 +0x81b
net/http.HandlerFunc.ServeHTTP(0x2cbc60, 0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
    /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1220 +0x40
net/http.(*ServeMux).ServeHTTP(0xc21001e5d0, 0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
    /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1496 +0x163
net/http.serverHandler.ServeHTTP(0xc21001f500, 0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
    /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1597 +0x16e
net/http.(*conn).serve(0xc210058300)
    /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1167 +0x7b7
created by net/http.(*Server).Serve
    /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1644 +0x28b

1 个答案:

答案 0 :(得分:2)

错误来自此行

fmt.Fprintf(w, "{ \"text\": \"Translated to German you said: '%s'\" }",
    f.Data.Translations[0].TranslatedText)

所以你没有得到任何Translations - 那个数组是空的。

您可能需要检查resp.Status以查看是否返回了错误。这不会作为错误返回 - 您需要自己检查。