【问题标题】:Get pointer on var obtained via interface获取通过接口获取的 var 上的指针
【发布时间】:2019-02-08 12:49:45
【问题描述】:

在下面的代码中

var a int
var b interface{}

b = a

fmt.Printf("%T, %T \n", a, &a)
fmt.Printf("%T, %T \n", b, &b)

输出:

int, *int 
int, *interface {}

我希望 &b 的类型是 int 上的指针。

我有两个问题:

1) 为什么它是 interface{} 上的指针?

2) 如何获得原始类型的指针?

【问题讨论】:

  • 只是一个挑剔/友好的建议:尽可能避免使用interface{}。这是一个强大的工具,有时你无法避免它,但对于语言新手来说,在他们真的不应该使用 interface{} 时,这是一个常见的错误

标签: pointers go interface address-operator


【解决方案1】:

&b => 这是address operator 应用于变量b,其类型为interface{}。所以&b 将是一个*interface{} 类型的指针,指向变量b。如果您获取T 类型变量的地址,则结果将始终为*T 类型。

无法从b获取变量a的地址,因为赋值:

b = a

只需将a 的值复制到b。它将a 的值包装在interface{} 类型的接口值中,并将该接口值存储到b 中。此值与a 完全分离。

一般来说,所有assignments 都会复制被分配的值。 Go 中没有引用类型。如果您首先将a 的地址存储在b 中,那么您可以获得最接近您想要的内容,例如:

b = &a

然后你可以使用type assertionb中取出a的地址,如下所示:

fmt.Printf("%T, %T \n", a, &a)
fmt.Printf("%T, %T \n", b, b.(*int))

这个输出(在Go Playground上试试):

int, *int
*int, *int

(注意:当你简单地打印b时,由于它是一个接口类型,fmt 包会打印包裹在其中的(具体)值。)

查看相关问题:

How to get a pointer to a variable that's masked as an interface?

Changing pointer type and value under interface with reflection

【讨论】:

    【解决方案2】:

    只是为了完成icza's answer。如果您不知道存储在接口中的值的类型(因此,您不能显式使用类型断言),您可以使用reflect 包:

    var a int
    var b interface{}
    b = &a
    fmt.Println(reflect.TypeOf(b))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-21
      • 2011-09-17
      • 2021-06-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多