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

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

Index out of Range with array of structs in Go

问题

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

  1. type service_config struct {
  2. Services []struct {
  3. Name string
  4. Command string
  5. Request map[string]interface{}
  6. }
  7. }
  8. var ServiceConf = service_config{}
  9. err_json := json.Unmarshal(file_content, &ServiceConf)
  10. for _, s := range ServiceConf.Services {
  11. log.Println(s)
  12. }

每次运行代码时,你都会得到以下错误信息:

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

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

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "log"
  7. "net/http"
  8. "net/url"
  9. "os"
  10. )
  11. type SlackResponse struct {
  12. token string
  13. team_id string
  14. channel_id string
  15. channel_name string
  16. timestamp string
  17. user_id string
  18. user_name string
  19. text string
  20. }
  21. type service_config struct {
  22. Services []struct {
  23. Name string
  24. Command string
  25. Request map[string]interface{}
  26. }
  27. }
  28. var ServiceConf = service_config{}
  29. func main() {
  30. content, err_read := ioutil.ReadFile("config.ini")
  31. if err_read != nil {
  32. log.Println("Could not read config")
  33. return
  34. }
  35. log.Println(string(content))
  36. err_json := json.Unmarshal(content, &ServiceConf)
  37. if err_json != nil {
  38. log.Println(err_json)
  39. }
  40. http.HandleFunc("/", handler)
  41. http.ListenAndServe(":"+os.Getenv("PORT"), nil)
  42. }
  43. func handler(w http.ResponseWriter, r *http.Request) {
  44. slack_response := SlackResponse{
  45. r.FormValue("token"),
  46. r.FormValue("team_id"),
  47. r.FormValue("channel_id"),
  48. r.FormValue("channel_name"),
  49. r.FormValue("timestamp"),
  50. r.FormValue("user_id"),
  51. r.FormValue("user_name"),
  52. r.FormValue("text"),
  53. }
  54. // log.Println(ServiceConf.Services[0].Request["key"])
  55. // loop through services to find command phrases
  56. for _, s := range ServiceConf.Services {
  57. log.Println(s)
  58. }
  59. if slack_response.user_name == "slackbot" {
  60. return
  61. }
  62. // fmt.Fprintf(w, "{ \"text\": \"Master %s! You said: '%s'\" }", slack_response.user_name, slack_response.text)
  63. content, err := getContent("https://www.googleapis.com/language/translate/v2?key=&source=en&target=de&q=" + url.QueryEscape(slack_response.text))
  64. if err != nil {
  65. fmt.Fprintf(w, "{ \"text\": \"Huh?!\" }")
  66. } else {
  67. type trans struct {
  68. Data struct {
  69. Translations []struct {
  70. TranslatedText string `json:"translatedText"`
  71. } `json:"translations"`
  72. } `json:"data"`
  73. }
  74. f := trans{}
  75. err := json.Unmarshal(content, &f)
  76. if err != nil {
  77. log.Println(err)
  78. }
  79. fmt.Fprintf(w, "{ \"text\": \"Translated to German you said: '%s'\" }", f.Data.Translations[0].TranslatedText)
  80. }
  81. }
  82. // array of bytes if retrieved successfully.
  83. func getContent(url string) ([]byte, error) {
  84. // Build the request
  85. req, err := http.NewRequest("GET", url, nil)
  86. if err != nil {
  87. return nil, err
  88. }
  89. // Send the request via a client
  90. client := &http.Client{}
  91. resp, err := client.Do(req)
  92. if err != nil {
  93. return nil, err
  94. }
  95. // Defer the closing of the body
  96. defer resp.Body.Close()
  97. // Read the content into a byte array
  98. body, err := ioutil.ReadAll(resp.Body)
  99. if err != nil {
  100. return nil, err
  101. }
  102. // At this point we're done - simply return the bytes
  103. return body, nil
  104. }

这是堆栈跟踪信息:

  1. 2014/03/21 23:21:29 http: panic serving [::1]:59508: runtime error: index out of range
  2. goroutine 3 [running]:
  3. net/http.func·009()
  4. /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1093 +0xae
  5. runtime.panic(0x215f80, 0x4b6537)
  6. /usr/local/Cellar/go/1.2/libexec/src/pkg/runtime/panic.c:248 +0x106
  7. main.handler(0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
  8. /Users/et/src/go/src/github.com/etdebruin/gojacques/main.go:100 +0x81b
  9. net/http.HandlerFunc.ServeHTTP(0x2cbc60, 0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
  10. /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1220 +0x40
  11. net/http.(*ServeMux).ServeHTTP(0xc21001e5d0, 0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
  12. /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1496 +0x163
  13. net/http.serverHandler.ServeHTTP(0xc21001f500, 0x5a85e8, 0xc21000f6e0, 0xc210037dd0)
  14. /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1597 +0x16e
  15. net/http.(*conn).serve(0xc210058300)
  16. /usr/local/Cellar/go/1.2/libexec/src/pkg/net/http/server.go:1167 +0x7b7
  17. created by net/http.(*Server).Serve
  18. /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:

  1. type service_config struct {
  2. Services []struct {
  3. Name string
  4. Command string
  5. Request map[string]interface{}
  6. }
  7. }
  8. var ServiceConf = service_config{}
  9. err_json := json.Unmarshal(file_content, &ServiceConf)
  10. for _, s := range ServiceConf.Services {
  11. log.Println(s)
  12. }

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

  1. {
  2. "services" : [
  3. {
  4. "name": "translation",
  5. "command": "to german",
  6. "request": {
  7. "key": "XXX",
  8. "url": "https://www.googleapis.com/language/translate/v2?"
  9. }
  10. }
  11. ]
  12. }

If you're interested in the complete source file:

  1. package main
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io/ioutil"
  6. "log"
  7. "net/http"
  8. "net/url"
  9. "os"
  10. )
  11. type SlackResponse struct {
  12. token string
  13. team_id string
  14. channel_id string
  15. channel_name string
  16. timestamp string
  17. user_id string
  18. user_name string
  19. text string
  20. }
  21. type service_config struct {
  22. Services []struct {
  23. Name string
  24. Command string
  25. Request map[string]interface{}
  26. }
  27. }
  28. var ServiceConf = service_config{}
  29. func main() {
  30. content, err_read := ioutil.ReadFile("config.ini")
  31. if err_read != nil {
  32. log.Println("Could not read config")
  33. return
  34. }
  35. log.Println(string(content))
  36. err_json := json.Unmarshal(content, &ServiceConf)
  37. if err_json != nil {
  38. log.Println(err_json)
  39. }
  40. http.HandleFunc("/", handler)
  41. http.ListenAndServe(":"+os.Getenv("PORT"), nil)
  42. }
  43. func handler(w http.ResponseWriter, r *http.Request) {
  44. slack_response := SlackResponse{
  45. r.FormValue("token"),
  46. r.FormValue("team_id"),
  47. r.FormValue("channel_id"),
  48. r.FormValue("channel_name"),
  49. r.FormValue("timestamp"),
  50. r.FormValue("user_id"),
  51. r.FormValue("user_name"),
  52. r.FormValue("text"),
  53. }
  54. // log.Println(ServiceConf.Services[0].Request["key"])
  55. // loop through services to find command phrases
  56. for _, s := range ServiceConf.Services {
  57. log.Println(s)
  58. }
  59. if slack_response.user_name == "slackbot" {
  60. return
  61. }
  62. // fmt.Fprintf(w, "{ \"text\": \"Master %s! You said: '%s'\" }", slack_response.user_name, slack_response.text)
  63. content, err := getContent("https://www.googleapis.com/language/translate/v2?key=&source=en&target=de&q=" + url.QueryEscape(slack_response.text))
  64. if err != nil {
  65. fmt.Fprintf(w, "{ \"text\": \"Huh?!\" }")
  66. } else {
  67. type trans struct {
  68. Data struct {
  69. Translations []struct {
  70. TranslatedText string `json:"translatedText"`
  71. } `json:"translations"`
  72. } `json:"data"`
  73. }
  74. f := trans{}
  75. err := json.Unmarshal(content, &f)
  76. if err != nil {
  77. log.Println(err)
  78. }
  79. fmt.Fprintf(w, "{ \"text\": \"Translated to German you said: '%s'\" }", f.Data.Translations[0].TranslatedText)
  80. }
  81. }
  82. // array of bytes if retrieved successfully.
  83. func getContent(url string) ([]byte, error) {
  84. // Build the request
  85. req, err := http.NewRequest("GET", url, nil)
  86. if err != nil {
  87. return nil, err
  88. }
  89. // Send the request via a client
  90. client := &http.Client{}
  91. resp, err := client.Do(req)
  92. if err != nil {
  93. return nil, err
  94. }
  95. // Defer the closing of the body
  96. defer resp.Body.Close()
  97. // Read the content into a byte array
  98. body, err := ioutil.ReadAll(resp.Body)
  99. if err != nil {
  100. return nil, err
  101. }
  102. // At this point we're done - simply return the bytes
  103. return body, nil
  104. }

Here is the stack trace:

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

答案1

得分: 2

错误来自这一行代码:

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

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

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

英文:

The error comes from this line

  1. fmt.Fprintf(w, "{ \"text\": \"Translated to German you said: '%s'\" }",
  2. 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:

确定