Go的临时地址?

Mat*_*ner 38 pointers return temporary rvalue go

处理这种情况最简洁的方法是什么:

func a() string {
    /* doesn't matter */
}

b *string = &a()
Run Code Online (Sandbox Code Playgroud)

这会生成错误:

不能取一个()的地址

我的理解是,如果采用地址,Go会自动将局部变量提升到堆中.这里很清楚,要采用返回值的地址.处理这个问题的惯用方法是什么?

zzz*_*zzz 38

地址运算符返回指向具有"home"的东西的指针,例如变量.代码中表达式的值是"无家可归者".如果你真的需要一个*字符串,你必须分两步完成:

tmp := a(); b := &tmp
Run Code Online (Sandbox Code Playgroud)

请注意,虽然*string的用例完全有效,但很多时候使用它们都是错误的.在Go中string是一个值类型,但是传递一个便宜的类型(指针和int).String的是不可变的,更改*string"home"指向的更改,而不是字符串值,因此在大多数情况下*string根本不需要.

  • 你也可以取一个复合文字的地址,它没有"家" (5认同)
  • 所有这些家庭和无家可归的胡言乱语.是否有比rvalue和lvalue更直观的命名法? (4认同)
  • 或者从`a()`返回一个`*string` (2认同)

new*_*cct 13

请参阅Go语言规范的相关部分.&只能用于:

  1. 可寻址的东西:变量,指针间接,切片索引操作,可寻址结构的字段选择器,可寻址数组的数组索引操作; 要么
  2. 复合文字

你拥有的不是那些,所以它不起作用.

即使你能做到,我也不确定它意味着什么.取一个函数调用的结果地址?通常,您将某事物的指针传递给某人,因为您希望它们能够分配给指向的事物,并查看原始变量中的更改.但是函数调用的结果是暂时的; 没有其他人"看到"它,除非你先把它分配给它.

如果创建指针的目的是创建具有动态生命周期的东西,类似于new()或获取复合文字的地址,那么您可以将函数调用的结果分配给变量并获取该地址.


小智 5

最后,您建议Go应该允许您获取任何表达式的地址,例如:

i,j := 1,2
var p *int = &(i+j)
println(*p)
Run Code Online (Sandbox Code Playgroud)

当前的Go编译器打印错误: cannot take the address of i + j

在我看来,允许程序员获取任何表达式的地址:

  • 似乎没有用处(也就是说:它似乎在实际的Go程序中出现的概率非常小).
  • 这会使编译器和语言规范复杂化.

将编译器和规范复杂化似乎适得其反.