Go语言中的接口可以是`(类型, nil)`或`(类型, 值)`的形式。

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

Go interface is (type, nil) or (type , value)

问题

你好,以下是翻译好的内容:

嗨,我想问一个关于接口为nil的问题。

//我认为err应该是一个接口(*MyError, nil)
var err error = (*MyError)(nil)
fmt.Println(reflect.TypeOf(err)) 
fmt.Println(reflect.ValueOf(err))

结果告诉我接口的值不是nil:
结果:

*main.MyError
<*main.MyError Value>

这相当于接口(*main.MyError, <*main.MyError Value>),为什么接口的值不是nil呢?

谢谢!

英文:

Hi I want ask a question about interface is nil <br>

//i think err should be a interface (*MyError, nil)
var err error = (*MyError)(nil)
fmt.Println(reflect.TypeOf(err)) 
fmt.Println(reflect.ValueOf(err))` 

the result told me interface value is not nil
result :

*main.MyError
&lt;*main.MyError Value&gt;

it's equivalent to interface (*main.MyError, &lt;*main.MyError Value&gt;)
why the interface value is not nil?

thanks

答案1

得分: 2

这两个东西完全不同:

  • nil 接口值。它不持有底层类型或值。

  • nil 接口值,它持有底层类型和值,并且该底层值在该底层类型中为 nil(如果它是具有名为 nil 的值的类型之一,如指针、切片、映射、通道或函数)。请注意,不同类型的 nil 是不同且无关的(指针-nil 和映射-nil 是无关的);而且有些类型没有名为 nil 的值。

你有一个 nil 指针(类型为 *MyError),然后将其赋值给一个接口变量(首先是接口类型 error,然后转换为接口类型 interface{},这是 reflect.TypeOf()reflect.ValueOf() 的参数类型)。因此,这些函数接收到一个非 nil 的接口值,其中包含底层类型 *MyError 和底层值 nil

reflect.TypeOf(err) 获取底层类型,即 *MyError。而 reflect.ValueOf(err) 构造一个表示底层类型和值的 reflect.Value 对象。这就是你看到的内容。

reflect.Value 的字符串化 会产生字符串 &lt;T value&gt;,其中 T 是类型,但它不会尝试将值(在这种情况下是 nil 指针)转换为字符串。如果你想打印底层值,也许你应该只是使用 fmt.Println(err)

英文:

These two things are completely different:

  • The nil interface value. It does not hold an underlying type or value.

  • A non-nil interface value, which holds an underlying type and value, and that underlying value is nil in that underlying type (if it's one of the types that have a value called nil -- pointer, slice, map, channel, or function). Note that different types' nils are different and unrelated (pointer-nil and map-nil are unrelated); and some types don't have a value called nil.

You have a nil pointer (*MyError type), and you assign that to an interface variable (first of interface type error, then converted to interface type interface{} which is the parameter type of reflect.TypeOf() and reflect.ValueOf()). Therefore, those functions receive a non-nil interface value containing an underlying type *MyError and underlying value nil.

reflect.TypeOf(err) gets the underlying type, which is *MyError. And reflect.ValueOf(err) constructs a reflect.Value object representing the underlying type and value. This is what you see.

The stringification of a reflect.Value produces the string &lt;T value&gt;, where T is the type, but it doesn't try to stringily the value (nil pointer in this case). If you wanted to print the underlying value, perhaps you should have just done fmt.Println(err) instead.

答案2

得分: 0

ValueOf函数返回一个新的Value,该Value被初始化为接口i中存储的具体值。ValueOf(nil)返回零值Value

英文:

http://golang.org/pkg/reflect/#ValueOf

> ValueOf returns a new Value initialized to the concrete value stored
> in the interface i. ValueOf(nil) returns the zero Value.

huangapple
  • 本文由 发表于 2014年8月14日 13:17:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/25300573.html
匿名

发表评论

匿名网友

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

确定