【问题标题】:GoLang: why doesn't address-of operator work without a variable declarationGoLang:为什么没有变量声明的地址运算符不起作用
【发布时间】:2021-09-14 12:21:58
【问题描述】:

在 Go 中,假设我有一个 UTF-8 的 []byte,我想将其作为字符串返回。

func example() *string {
   byteArray := someFunction()
   text := string(byteArray)
   return &text
}

我想去掉 text 变量,但 Go 不支持以下内容:

func example() *string {
   byteArray := someFunction()
   return &string(byteArray)
}

第二个示例语法正确吗?如果是这样,为什么 Go 不支持它?

【问题讨论】:

  • 有什么具体原因,为什么要在这种情况下处理指针?为什么不在函数中返回字符串值。如果你真的需要指针而不是值,然后使用指针语法
  • 消除指针是一个不错的建议。如果函数也返回错误,我认为指针对错误路径很有帮助,例如,return nil, err 而不是return "", err
  • 这只是语言作者在设计时的决定。 Note that you can write return &T{1, "two"},那为什么不return &3?但你不能那样做。为什么不?因为上帝,我的意思是肯,是这么说的。
  • @torek 我觉得不允许 & 是对的,但不支持 & 是出乎意料的。你又举了一个我没想到的例子,很有趣!

标签: go


【解决方案1】:

因为spec 是这样定义的:

对于类型为 T 的操作数 x,地址操作 &x 生成指向 x 的 *T 类型的指针。操作数必须是可寻址的,即变量、指针间接或切片索引操作;或可寻址结构操作数的字段选择器;或可寻址数组的数组索引操作。作为可寻址性要求的一个例外,x 也可以是(可能是带括号的)复合文字。

请注意,type conversions(您尝试对 string(byteArray) 执行的操作)未包含在此列表中。

【讨论】:

  • 感谢您的规范,但我仍然不清楚。我想了解为什么string(byteArray) 不可寻址,以及排除这种可能性的动机。
  • 引用的文本为您提供了可寻址操作数的完整列表。类型转换不是其中之一。至于原因,您需要询问 Go 的作者。
  • @jws: "addressable" 大致意思是“在内存中有一个位置”,在你把它赋值给一个变量之前,这个值是不会存储在内存中的。
  • @jws 整个社区无法说出拥有这种动机的特定少数人(语言作者)的动机。你得问问他们。
【解决方案2】:

有关官方引用,请参阅 Marc 的回答,但这是 Go 不支持这一点的直观原因。

假设如下代码

var myString string
stringPointer := &myString
*stringPointer = "some new value"

希望您知道,这段代码会将一些新值写入myString。这是指针的基本用法。现在考虑修改后的示例(假设它是有效代码):

var myBytes []byte
// modify myBytes...
stringPointer := &string(myString)
*stringPointer = "some new value"

问题是,我们在世界上的哪个地方(或计算机)写信?一些新的价值将走向何方?

为了让语言正确处理这个问题,编译器需要一些内部过程来将临时值“提升”为不可见变量,然后获取该变量的地址。这将增加不必要的复杂性以使 一些 代码稍微 更短,但会造成这种混乱的情况,即我们的指针在程序中没有明确定义的位置。该语言没有创建这些令人困惑的幽灵变量,而是委托程序员照常使用他们自己的变量。

【讨论】:

  • 很好的答案。该语言可以生成隐式匿名变量,但是对于有限的好处来说,这是一个丑陋的并发症。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-14
  • 1970-01-01
  • 1970-01-01
  • 2013-07-10
  • 2012-06-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多