如何在 Golang 中检查变量是否为 nil?

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

how to golang check a variable is nil

问题

我的代码是这样的,当我使用req, _ := http.NewRequest("GET", "http://www.github.com", content)时,会出现异常:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0xffffffff addr=0x0 pc=0xaab78]

goroutine 1 [running]:
net/http.NewRequest(0x34f3b8, 0x3, 0x378020, 0x15, 0xfeec4350, 0x0, 0x10738801, 0x0, 0x0, 0x107000e0)
	/usr/local/go/src/net/http/request.go:570 +0x498
main.main()
	/tmp/sandbox056954284/main.go:17 +0xe0

但是当我使用req, _ := http.NewRequest("GET", "http://www.github.com", nil)时,它可以正常工作,为什么?我如何设置第三个参数的值

package main

import (
	"bytes"
	"net/http"
)


func main() {
    client := &http.Client{}
    var content *bytes.Reader
    content = nil
    req, _ := http.NewRequest("GET", "http://www.github.com", content)
	resp, _ := client.Do(req)
	defer resp.Body.Close()
}
英文:

my code is like this, when I use req, _ := http.NewRequest("GET", "http://www.github.com", content), it will emit exception:

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0xffffffff addr=0x0 pc=0xaab78]

goroutine 1 [running]:
net/http.NewRequest(0x34f3b8, 0x3, 0x378020, 0x15, 0xfeec4350, 0x0, 0x10738801, 0x0, 0x0, 0x107000e0)
	/usr/local/go/src/net/http/request.go:570 +0x498
main.main()
	/tmp/sandbox056954284/main.go:17 +0xe0

but when I use req, _ := http.NewRequest("GET", "http://www.github.com", nil), it works, why? how I set the third argument value

package main

import (
	"bytes"
	"net/http"
)


func main() {
    client := &http.Client{}
    var content *bytes.Reader
    content = nil
    req, _ := http.NewRequest("GET", "http://www.github.com", content)
	resp, _ := client.Do(req)
	defer resp.Body.Close()
}

答案1

得分: 6

一个Go接口由类型和值组成。只有当类型和值都为nil时,接口才为nil。你提供了一个类型但没有值:因此,NewRequest尝试在一个nil结构体上调用Read方法(接口的值)。

英文:

A go interface consists of a type and a value. An interface is only nil if both the type and the value are nil. You provided a type but no value: Therefore NewRequest tried to call Read on a nil struct (the value of the interface).

答案2

得分: 3

content默认为nil,不需要赋值。

另外,你忽略了NewRequest返回的错误,请不要这样做。它会告诉你为什么无法生成请求。

正常的错误处理应该是这样的:

req, err := http.NewRequest("GET", "http://www.github.com", content)
if err != nil {
  // 记录日志或者报错... 这里req是nil
} else {
  // 对req进行操作
}

总之,如果你只是想知道req是否为nil,可以这样做:

if req == nil { 
 // 处理nil的req
} else {
 // 使用req
}

但是如前所述,最好处理错误。如果err不为nil,那么基本上不能信任req是否有效。

英文:

content is nil by default, don't need to assign it

also, you are ignoring the error returned from NewRequest, don't do that. It is telling you why it can't generate a request.

Normal error handling would be something like:

req, err := http.NewRequest("GET", "http://www.github.com", content)
if err != nil {
  // log or complain... req is nil here
} else {
  // do something with req
}

all that said if you really just want to know if req is nil, do:

if req == nil { 
 // handle nil req
} else {
 // use req
}

but as mentioned before, it's much better to handle the error. if err not nil, then you basically can't trust req to be anything valid.

答案3

得分: 2

这是golang语言的一个经典陷阱。

要检查是否为真正的Nil:

p == nil || reflect.ValueOf(p).IsNil()

参考链接:
https://www.mangatmodi.com/posts/go-check-nil-interface-the-right-way/

英文:

It is a classic trap of the golang language.

To check if it is a real Nil:

p == nil || reflect.ValueOf(p).IsNil()

Reference:
https://www.mangatmodi.com/posts/go-check-nil-interface-the-right-way/

huangapple
  • 本文由 发表于 2015年10月30日 08:23:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/33426977.html
匿名

发表评论

匿名网友

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

确定