为什么接口类型不提供“IsNil”方法? [英] Why interface type doesn't provide an "IsNil" method?
问题描述
$ b $ pre $
func process(body io.Reader){
fmt.Printf( body == nil?%+ v \ n,body == nil)
}
func main(){
var body * bytes.Buffer
fmt.Printf(body == nil?%+ v \ n,body == nil)
process(body)
process(nil)
}
以下是输出:
body == nil?真
正文==零?假//你有这个权利吗?
正文==零? true
另一个例子:
type Container struct {
Reader io.Reader
}
func processContainer(container Container){
fmt.Printf(container。 Reader == nil?%+ v \ n,container.Reader == nil)
}
func main(){
var body * bytes.Buffer
processContainer(Container {Reader:body})
processContainer(Container {Reader:nil})
}
输出:
container.Reader == nil?假//你有这个权利吗?
container.Reader == nil?真正的
这个解释在 https://golang.org/doc/faq#nil_error 。
一个天真的解决方案是如果接口对象包含 另外一个例子,这个来自Go http客户端的线路,可以很好地捕捉到你: https:/ /github.com/golang/go/blob/master/src/net/http/client.go#L545 所以如果你这样称呼它 即使从源代码的角度看,这也不会发生,你会得到一个零指针异常。 / p> 编辑 抱歉,我引用了Go http源的错误行,现在纠正了。 编辑2 我已经突出了我的问题,以说明我在问什么。 nil
值,那么使 == nil
test只返回true。但是这会违反 ==
的传递性,因为它会在 == $ c $下声明两个具有零值但接口类型不同的对象不过,我想知道所有接口上是否应该有一个
IsNil()
方法类型,这可以解决这个问题吗?
var body * bytes.Buffer
http.NewRequest(method,path,body)
code>
但是这个例子仍然存在。
通过将接口值与 如果你想检查一个非 - 请参阅此修改示例: 输出(在 Go Playground ): 如果你想要一个统一 First let's consider the following: And here's the output: Another example: Output: The explanation for this is at https://golang.org/doc/faq#nil_error. A naive solution is to make the However, I wonder if there should be an Another example, this line from Go http client, can catch you unexpectedly: https://github.com/golang/go/blob/master/src/net/http/client.go#L545 So if you call it like this You'll get a nil pointer exception, even though, by the look of the source code, this shouldn't happen. Edit Sorry I referenced the wrong line of the Go http source, now corrected.
But the example still holds. Edit 2 I've highlighted my question to make it clear what I'm asking. First read this related question: Hiding nil values, understanding why golang fails here You can check if the interface value itself is If you want to check if the value wrapped inside a non- See this modified example: Output (try it on the Go Playground): If you want a "unified"
这篇关于为什么接口类型不提供“IsNil”方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! nil $ c进行比较,您可以检查接口值本身是否为
nil
$ c $。
$ b nil
接口中的值是否为 nil
,您可以使用反射: reflect.Value.IsNil()
。
func process(body io.Reader){
fmt.Printf(process():body == nil?%t \\\
,正文==无)
如果body!= nil {
fmt.Println(\ tINSIDE IsNil():,reflect.ValueOf(body).IsNil())
}
}
func main(){
var body * bytes.Buffer
fmt.Printf(main():body == nil? %t $ \\ n,body == nil)
process(body)
process(nil)
process(& bytes.Buffer {})
}
main():body == nil ():真正的
process():body == nil?false
INSIDE IsNil():true
process():body == nil?true
process():body = = nil?false
INSIDE IsNil():false
IsNil()
函数,它告诉是否 nil
:
func IsNil(i interface {})bool {
return i == nil || reflect.ValueOf(i).IsNil()
}
func process(body io.Reader) {
fmt.Printf("body == nil ? %+v\n", body == nil)
}
func main() {
var body *bytes.Buffer
fmt.Printf("body == nil ? %+v\n", body == nil)
process(body)
process(nil)
}
body == nil ? true
body == nil ? false // Did you get this right?
body == nil ? true
type Container struct {
Reader io.Reader
}
func processContainer(container Container) {
fmt.Printf("container.Reader == nil ? %+v\n", container.Reader == nil)
}
func main() {
var body *bytes.Buffer
processContainer(Container{Reader: body})
processContainer(Container{Reader: nil})
}
container.Reader == nil ? false // Did you get this right?
container.Reader == nil ? true
== nil
test just return true if the interface object contains nil
value. But this would violate transitivity of ==
, as it would assert two objects with nil value but different interface types true under ==
.IsNil()
method on all interface types, which would solve this issue?var body *bytes.Buffer
http.NewRequest(method, path, body)
nil
by comparing it to nil
.nil
interface is nil
, you can use reflection: reflect.Value.IsNil()
.func process(body io.Reader) {
fmt.Printf("process(): body == nil ? %t\n", body == nil)
if body != nil {
fmt.Println("\tINSIDE IsNil():", reflect.ValueOf(body).IsNil())
}
}
func main() {
var body *bytes.Buffer
fmt.Printf("main(): body == nil ? %t\n", body == nil)
process(body)
process(nil)
process(&bytes.Buffer{})
}
main(): body == nil ? true
process(): body == nil ? false
INSIDE IsNil(): true
process(): body == nil ? true
process(): body == nil ? false
INSIDE IsNil(): false
IsNil()
function which tells if either is nil
:func IsNil(i interface{}) bool {
return i == nil || reflect.ValueOf(i).IsNil()
}