当前位置: 首页 > 面试题库 >

将nil接口转换为Golang中某物的指针?

欧金鹏
2023-03-14
问题内容

在以下代码段中,尝试将nil接口转换为某物的指针失败,并出现以下错误: interface conversion: interface is nil, not *main.Node

type Nexter interface {
    Next() Nexter
}

type Node struct {
    next Nexter
}

func (n *Node) Next() Nexter {...}

func main() {
    var p Nexter

    var n *Node
    fmt.Println(n == nil) // will print true
    n = p.(*Node) // will fail
}

在此处播放链接:https :
//play.golang.org/p/2cgyfUStCI

为什么这会完全失败?完全有可能做

n = (*Node)(nil)

,所以我想知道如何从nil接口开始实现类似的效果。


问题答案:

这是因为 静态 类型的变量Nexter(只是一个接口)可能包含许多不同 动态 类型的值。

是的,因为*Node工具Nexter,您的p变量 可能 持有类型的值*Node,但它可以容纳 其他类型 以及其实施Nexter;
或者它可能持有 什么
都(nil值)。而且类型断言不能在这里使用,因为引用了规范:

x.(T)断言xnil存储在值x是类型的T

但是x你的情况是nil。如果类型断言为假, 则会发生运行时恐慌

如果您更改程序以使用以下方法初始化p变量:

var p Nexter = (*Node)(nil)

您的程序将运行,并且类型声明成功。这是因为接口值实际上以以下形式持有一对:(value, dynamic type),在这种情况下,您p将不是nil,但将持有一对(nil, *Node);有关详细信息,请参见反射定律#接口的表示。

如果您还想处理nil接口类型的值,则可以像下面这样显式检查它:

if p != nil {
    n = p.(*Node) // will not fail IF p really contains a value of type *Node
}

或者更好:使用特殊的“逗号分隔”形式:

// This will never fail:
if n, ok := p.(*Node); ok {
    fmt.Printf("n=%#v\n", n)
}

使用“逗号分隔”形式:

如果断言成立,ok则值为true。否则,它是false和值n是类型的零值T在这种情况下,不会发生运行时恐慌。



 类似资料:
  • 问题内容: 我想在下面的代码中改进getCustomerFromDTO方法,我需要从interface {}创建一个结构,目前我需要将该接口编组为byte [],然后将数组解组为我的结构-必须有更好的方法。 我的用例是,我通过rabbitmq发送结构,然后使用具有其他特定于域的数据的通用DTO包装器来发送它们。当我从Rabbit MQ接收DTO时,消息下方的一层将被封送给我的DTO,然后我需要从该

  • 问题内容: 我正在使用github.com/fatih/structs包将struct的所有字段的值转换为函数。看这里。这工作正常,但最终我想通过使用csv包将值写入csv文件。该功能需要作为输入。 简而言之:我如何轻松地将的输出转换为字符串数组? 问题答案: 即使所有值都是具体类型,也不能简单地转换为,因为这两种类型具有不同的内存布局/表示形式。 您必须定义如何用值表示不同类型的值。 最简单和明

  • 问题内容: 如果我有: 上面是固定的-我不能更改foo或bar。另外,baz必须在bar内转换回foo struct指针。如何将&foo {}强制转换为interface {},以便在调用bar时可以将其用作参数? 问题答案: 要打开到一个很简单: 为了返回到,您可以执行 类型断言 : 或 类型开关 (类似,但可以是多种类型则很有用):

  • 问题内容: 在进行中,是否可以通过某种方式动态地转换变量? 例如,如果简单的转换将是: 如果我事先不知道年龄是整数怎么办?一种简单的书写方式是 有没有办法实现这样的目标?反射包提供了一些在运行时确定或强制转换类型的方法-但我找不到像上述提到的东西(适用于所有类型的通用方案)。 问题答案: 不,你不能。Go是一种静态类型的语言。变量的类型在编译时确定。 如果要动态确定的,可以使用类型切换:

  • 问题内容: 我正在尝试编写一个将接受所有数据类型的哈希。一旦进入函数,我将数据作为字节数组处理。我在弄清楚如何将任意类型转换为字节数组时遇到麻烦。 我尝试使用二进制包,但它似乎取决于传入的数据类型。fn (docs)的参数之一需要知道参数的字节顺序。 所有数据类型的大小都是字节的某个倍数(甚至是布尔值),因此理论上这应该很简单。 下面有问题的代码, 问题答案: 代码中的其他问题使我较早离开了软件包

  • 问题内容: 看到这个游乐场:http : //play.golang.org/p/nWHmlw1W01 为什么两个函数的输出不同? 问题答案: 诚然,这有点古怪,但是有一个解释。 想象一个变量是由两个字段组成的结构:一个是类型,另一个是数据。(和)。实际上,它看起来就像Go运行时中的样子。 当您将nil slice传递给时,只会将其作为值传递,因此您的比较可简化为。 同时,调用会自动将您的变量包装