在go中查找constant的地址

时间:2016-02-02 06:11:55

标签: pointers go constants

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

package main

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

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

3 个答案:

答案 0 :(得分:20)

简而言之:你不能

错误消息显示:

  

不能取k的地址

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

  

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

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

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

  1. 常数可能根本没有地址。
  2. 即使在运行时将常量值存储在内存中,也可以帮助运行时保持以下常量:常量。如果你可以获取常量值的地址,你可以将地址(指针)分配给变量,你可以改变它(指向的值,常量的值)。
  3. 如果需要指向一个等于该常量的值的指针,请将其指定给一个可寻址的变量,这样就可以获取其地址,例如

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

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

答案 1 :(得分: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不必先声明大的变量块,而使IMO更具可读性/麻烦。

答案 2 :(得分:-3)

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

结果,它们似乎 1 具有无限精度。如果你看一下this example,你可以看到我可以将常量分配给一个变量而不需要它,并且变量将保持尽可能多的常量精度。

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