Golang中的nil在http请求中的含义是什么?

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

Golang, nil in http requests

问题

我正在创建一个Go脚本,从一个API中获取尽可能多的HTTP请求。

当我使用多个goroutine调用worker()时,具体来说是超过200个goroutine时,我在soundcloud.GetUser(i)这一行遇到了空指针引用的错误。

这是我确切遇到的错误:

  1. goroutine 28 [running]:
  2. runtime.panic(0x75fca0, 0x98cf13)
  3. /usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5 www.github.com/Juanvulcano/gosoundcloud%2egit.processAndUnmarshalResponses(0x0, 0x7f1d338e9fd0, 0xc209467a10, 0x780a60, 0xc20809c300, 0x0, 0x0)
  4. /home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/gosoundcloud.go:31 +0x413
  5. www.github.com/Juanvulcano/gosoundcloud%2egit.(*SoundcloudApi).GetUser(0xc208040520, 0x2, 0x7f1d41e81f40, 0x0, 0x0)
  6. /home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/soundcloud.go:295 +0x1b1
  7. main.worker()
  8. /home/maker/go/src/GoBot/GoBot.go:28 +0xdd
  9. created by main.main
  10. /home/maker/go/src/GoBot/GoBot.go:71 +0x55d

这里是我代码的重要部分:

  1. func worker() {
  2. defer wg.Done()
  3. for i := range input {
  4. member, err := soundcloud.GetUser(uint64(i))
  5. if err != nil{
  6. fmt.Println(err)
  7. }
  8. if member != nil {
  9. output <- fmt.Sprint(member.Username)
  10. }
  11. }
  12. }
  13. func main() {
  14. var err error
  15. if err = soundcloud.PasswordCredentialsToken("email", "password"); err != nil {
  16. fmt.Println(err)
  17. os.Exit(1)
  18. }
  19. go func() {
  20. for i := 1; i < 1000; i++ {
  21. input <- i
  22. }
  23. close(input)
  24. wg.Wait()
  25. close(output)
  26. }()
  27. for i := 0; i < 200; i++ {
  28. wg.Add(1)
  29. go worker()
  30. }
  31. printOutput()
  32. }
英文:

I'm creating a Go script to get as many http requests as possible from an API.

I'm getting a nil pointer reference at the line of soundcloud.GetUser(i) when I call worker() with multiple goroutines, more than 200 to be exact.

This is the error I'm getting to be exact.

  1. goroutine 28 [running]:
  2. runtime.panic(0x75fca0, 0x98cf13)
  3. /usr/lib/go/src/pkg/runtime/panic.c:279 +0xf5 www.github.com/Juanvulcano/gosoundcloud%2egit.processAndUnmarshalResponses(0x0, 0x7f1d338e9fd0, 0xc209467a10, 0x780a60, 0xc20809c300, 0x0, 0x0)
  4. /home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/gosoundcloud.go:31 +0x413
  5. www.github.com/Juanvulcano/gosoundcloud%2egit.(*SoundcloudApi).GetUser(0xc208040520, 0x2, 0x7f1d41e81f40, 0x0, 0x0)
  6. /home/maker/go/src/www.github.com/Juanvulcano/gosoundcloud.git/soundcloud.go:295 +0x1b1
  7. main.worker()
  8. /home/maker/go/src/GoBot/GoBot.go:28 +0xdd
  9. created by main.main
  10. /home/maker/go/src/GoBot/GoBot.go:71 +0x55d

Here I'm attaching the important parts of my code.

  1. func worker() {
  2. defer wg.Done()
  3. for i := range input {
  4. member, err := soundcloud.GetUser(uint64(i))
  5. if err != nil{
  6. fmt.Println(err)
  7. }
  8. if member != nil {
  9. output <- fmt.Sprint(member.Username)
  10. }
  11. }
  12. }
  13. func main() {
  14. var err error
  15. if err = soundcloud.PasswordCredentialsToken("email", "password"); err != nil {
  16. fmt.Println(err)
  17. os.Exit(1)
  18. }
  19. go func() {
  20. for i := 1; i < 1000; i++ {
  21. input <- i
  22. }
  23. close(input)
  24. wg.Wait()
  25. close(output)
  26. }()
  27. for i := 0; i < 200; i++ {
  28. wg.Add(1)
  29. go worker()
  30. }
  31. printOutput()
  32. }

答案1

得分: 2

在这个函数中:

  1. func processAndUnmarshalResponses(resp *http.Response, err error, holder interface{}) error {
  2. defer resp.Body.Close()
  3. if err != nil {
  4. return err
  5. }

你在检查错误之前延迟执行了resp.Body.Close()。如果出现错误,resp将为nil,对其进行解引用将导致恐慌。请始终先进行错误检查。

英文:

in the function:

  1. func processAndUnmarshalResponses(resp *http.Response, err error, holder interface{}) error {
  2. defer resp.Body.Close()
  3. if err != nil {
  4. return err
  5. }

You are defering resp.Body.Close() before you check the error. If there is an error, resp will be nil, and dereferencing it will panic. Always put the error check first.

huangapple
  • 本文由 发表于 2016年5月26日 07:14:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/37449117.html
匿名

发表评论

匿名网友

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

确定