在go中查找constant的地址

问题描述 投票:11回答:3

我们编写了一个程序,通过它我们试图找到一个常量的地址。有可能这样做吗?

package main

func main() {
        const k = 5
        address := &k
}

它给出了一个错误,任何人都可以告诉我们如何找到常量的地址?

pointers go constants
3个回答
21
投票

简而言之:你做不到。

错误消息说:

不能取k的地址

地址运算符&的操作数有限制。 Spec: Address operators:

对于x类型的操作数T,地址操作&x生成*T类型的指针到x。操作数必须是可寻址的,即,变量,指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或者可寻址数组的数组索引操作。作为可寻址性要求的一个例外,x也可能是(可能是带括号的)composite literal。如果对x的评估会导致run-time panic,那么对&x的评估也是如此。

常量未列为可寻址,并且未在规范中列为可寻址(上面引用)的内容不能是地址运算符&的操作数(不能取其地址)。

不允许采用常量的地址。这有两个原因:

  1. 常量可能根本没有地址。
  2. 即使在运行时将常量值存储在内存中,这也是为了帮助运行时保持常量:常量。如果你可以获取常量值的地址,你可以将地址(指针)分配给变量,你可以改变它(指向的值,常量的值)。

如果需要一个指向值等于该常量的指针,请将其指定给一个可寻址的变量,这样就可以获取其地址,例如:

func main() {
    const k = 5
    v := k
    address := &v // This is allowed
}

但是要知道Go中的数字常量表示任意精度的值而不会溢出。当您将常量的值赋给变量时,可能无法实现(例如,常量可能大于您为其分配的变量类型的最大值 - 导致编译时错误),或者它可能不相同(例如,在浮点常数的情况下,它可能会失去精度)。


1
投票

在单元测试期间创建大型嵌套JSON对象时,我经常遇到此问题。我可能有一个结构,其中所有字段都是指向字符串/整数的指针:

type Obj struct {
    Prop1  *string
    Prop2  *int
    Status *string
}

并想写一些类似的东西:

obj := Obj{
    Prop1:  &"a string property",
    Prop2:  &5,
    Status: &statuses.Awesome,
}

当我初始化它时,但语言不允许直接使用它。绕过这个的一种快速方法是定义一个取常量并返回其地址的函数:

 s := func(s string) *string { return &s }
 i := func(s int) *int { return &i }

 obj := Obj{
    Prop1:  s("a string property"),
    Prop2:  i(5),
    Status: s(statuses.Awesome)
}

这是因为当常量作为参数传递给函数时,会产生一个常量的副本,这意味着在函数中创建的指针不指向常量的地址,而是指向其的地址。复制,与将常量值分配给var的方式相同。但是,使用函数执行此操作会使IMO比转发声明大块变量更易读/更麻烦。


-3
投票

constants部分没有说清楚:与变量不同,常量不存在于编译代码或运行程序中。它们是无类型的,只有在分配给变量后才会在内存中。

结果,他们似乎具有无限的精确度。如果你看一下this example,你可以看到我可以将常量赋值给一个变量,而不需要强制转换它,变量将保持尽可能多的常量精度。


1正如spec也指出的那样,整数至少有256位,浮点数至少为256位尾数和32位指数,如果内部结构无法准确存储常量,编译器将抛出错误。

© www.soinside.com 2019 - 2024. All rights reserved.