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

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

Golang, nil in http requests

问题

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

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

这是我确切遇到的错误:

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

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

func worker() {
   defer wg.Done()
   for i := range input {
       member,  err := soundcloud.GetUser(uint64(i))
       if err != nil{
           fmt.Println(err)
       }
       if member != nil {
           output <- fmt.Sprint(member.Username)
       }
    }
}    


func main() {    
    var err error
    if err = soundcloud.PasswordCredentialsToken("email", "password"); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }  
    go func() {    
        for i := 1; i < 1000; i++ {
                input <- i
       }
       close(input)
       wg.Wait()
       close(output)
    }()

    for i := 0; i < 200; i++ {
        wg.Add(1)
	    go worker()
    }    
    printOutput()
}
英文:

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.

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

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

func worker() {
   defer wg.Done()
   for i := range input {
       member,  err := soundcloud.GetUser(uint64(i))
       if err != nil{
           fmt.Println(err)
       }
       if member != nil {
           output <- fmt.Sprint(member.Username)
       }
    }
}    


func main() {    
    var err error
    if err = soundcloud.PasswordCredentialsToken("email", "password"); err != nil {
        fmt.Println(err)
        os.Exit(1)
    }  
    go func() {    
        for i := 1; i < 1000; i++ {
                input <- i
       }
       close(input)
       wg.Wait()
       close(output)
    }()

    for i := 0; i < 200; i++ {
        wg.Add(1)
	    go worker()
    }    
    printOutput()
}

答案1

得分: 2

在这个函数中:

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

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

英文:

in the function:

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

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:

确定