栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

隐藏nil值,了解golang为什么会失败

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

隐藏nil值,了解golang为什么会失败

这里的问题是那

shower
是一种
interface
类型。Go中的接口类型保存实际值及其 动态
类型。关于此的更多详细信息:反射定律#接口的表示。

您返回的切片包含2个非

nil
值。第二个值是一个接口值,一个保存
nil
指针值的(值;类型)对和一个
*display
具体类型。从Go语言规范中引用:比较运算符:

接口值是可比较的。如果两个接口值具有相同的动态类型和相等的动态值,或者两个值都具有value,则它们是相等的

nil

所以,如果你把它比作

nil
,这将是
false
。如果将其与代表该对的接口值进行比较
(nil;*display)
,则将为
true

if x == (*display)(nil) {    panic("everything ok, nil found")}

这似乎不可行,因为您必须知道接口所持有的实际类型。但是请注意,您可以使用反射来判断非

nil
接口值是否使用来包装
nil
Value.IsNil()
。您可以在Go
Playground
上看到一个示例。

为什么以这种方式实施?

与其他具体类型不同的接口(非接口)可以容纳不同具体类型的值(不同的静态类型)。运行时需要知道存储在接口类型变量中的值的动态类型或运行时类型。

An

interface
只是一个方法集,如果相同方法属于该类型的方法集的一部分,则
任何类型都可以
实现它。有些类型不能为,例如或为其基础类型的自定义类型。在这些情况下,您将不需要能够存储该特定类型的值。
nil``struct``int``nil

但是 任何类型
还包括

nil
有效值(例如切片,地图,通道,所有指针类型)的具体类型,因此,为了在运行时存储满足接口要求的值,可以合理地支持
nil
在接口内部进行存储。但是除了
nil
接口内部,我们还必须存储其动态类型,因为该
nil
值不包含此类信息。
nil
当要存储在其中的值是时,替代选项将用作接口值本身
nil
,但是此解决方案不足,因为它将丢失动态类型信息。

有人说Go的接口是动态类型的,但这是误导的。它们是静态类型的:接口类型的变量始终具有相同的静态类型,即使在运行时存储在接口变量中的值可能会更改类型,该值也将始终满足接口的要求。

通常,如果要指示类型

nil
的值
interface
,请使用显式
nil
值,然后可以测试是否
nil
相等。最常见的示例是内置
error
类型,它是一种方法的接口。只要没有错误,就可以显式设置或返回值,
nil
而不是某些具体(非接口)类型的错误变量的值(这实际上是错误的做法,请参见下面的演示)。

在您的示例中,混淆源于以下事实:

  • 您想要一个值作为接口类型(
    shower
  • 但是您要存储在切片中的值不是类型
    shower
    而是具体类型

因此,当您将一个

*display
类型放入
shower
切片中时,将创建一个接口值,该接口值是一对(value;
type),其中value是
nil
且type是
*display
。该对中的
将是
nil
,而不是接口值本身。如果您将一个
nil
值放入分片中,则接口值 本身
nil
,条件
x == nil
true

示范

请参见以下示例:操场

type MyErr stringfunc (m MyErr) Error() string {    return "big fail"}func doSomething(i int) error {    switch i {    default:        return nil // This is the trivial true case    case 1:        var p *MyErr        return p // This will be false    case 2:        return (*MyErr)(nil) // Same as case 1    case 3:        var err error // Zero value is nil for the interface        return err    // This will be true because err is already interface type    case 4:        var p *MyErr        return error(p) // This will be false because the interface points to a  // nil item but is not nil itself.    }}func main() {    for i := 0; i <= 4; i++ {        err := doSomething(i)        fmt.Println(i, err, err == nil)    }}

输出:

0 <nil> true1 <nil> false2 <nil> false3 <nil> true4 <nil> false

在情况2

nil
中,返回了一个指针,但首先将其转换为接口类型(
error
),因此创建了一个接口值,其中包含一个
nil
值和该类型
*MyErr
,因此该接口值不是
nil



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/375709.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号