在Go语言中,数组结构的索引超出范围了。

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

Index out of Range with array of structs in Go

问题

我刚刚阅读了你提供的代码和问题。你的问题是在迭代结构体数组时遇到了“index out of range”错误。你已经确认数组不为空,并且至少包含一个Services结构体。以下是你提供的代码的翻译:

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

如果你对完整的源文件感兴趣,可以查看以下代码:

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

希望这些信息对你有帮助!如果你有任何其他问题,请随时问我。

英文:

I am new to Go so hopefully I'm making myself clear with this issue I'm having. My problem is that I am trying to iterate over an array of structs but I keep running into an index out of range issue. For the purposes of this problem, I have already verified that my array is not empty but that it in fact does contain at least one Services struct and file_content is the string that contains my valid JSON

Here is the snippet of code that represents the problem I'm having:

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)
}

So every time I run my code I get:

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?"
}
}
]
}

If you're interested in the complete source file:

    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
}

Here is the stack trace:

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

得分: 2

错误来自这一行代码:

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

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

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

英文:

The error comes from this line

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

So you didn't get any Translations back - that array is empty.

You might want to check resp.Status to see if an error was returned. This isn't returned as an error - you need to check it yourself.

huangapple
  • 本文由 发表于 2014年3月16日 06:07:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/22430354.html
匿名

发表评论

匿名网友

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

确定