【问题标题】:Go fails to infer type in assignment: "non-name on left side of :="Go 无法推断分配类型:“:=”左侧的非名称
【发布时间】:2014-01-25 01:11:46
【问题描述】:

这个 sn-p 按预期工作play.golang.org/p/VuCl-OKMav

i := 10
next := 11
prev, i := i, next

然而,这个几乎相同的 sn-p 给出了 non-name f.Bar on left side of := play.golang.org/p/J8NNWPugQG

type Foo struct {
    Bar int
}

f := Foo{10}
next := 11
prev, f.Bar := f.Bar, next

停止类型推断的结构有什么特别之处?这是一个错误吗?

【问题讨论】:

    标签: go type-inference


    【解决方案1】:

    这是一个 open 问题。

    Issue 6842: 规范:分配给具有短声明符号的字段

    【讨论】:

      【解决方案2】:

      这不是真正的类型推断问题,只是:= 的左侧必须是标识符列表,而f.Bar 不是标识符,因此不能声明——甚至不能声明使用:= 对其可以声明的内容稍微宽松一些的规则。见"Short variable declarations" in The Go Programming Language Specification。

      【讨论】:

      • 一个相关问题:是否有理由不扩展短变量声明的规范以允许任何可分配的名称?
      • @deft_code:我不知道。我怀疑这会使解析器有些复杂,因为如果任意复杂的表达式(带有函数调用和指针取消引用等)可以出现在左侧(早在解析器看到 := 之前),那么解析器就有在更复杂的上下文中临时允许未声明的标识符(直到它看到:= 或可以排除它正在解析一个短变量声明)。但不知道是不是这个原因。也许语言设计者只是觉得prev, i := i, next 是一个他们愿意做的大例外。
      【解决方案3】:

      来自规范的Short variable declarations 部分:

      与常规变量声明不同,短变量声明可以 重新声明变量,前提是它们最初是在 相同的块...具有相同的类型,并且至少有一个非空白 变量是新的。

      因此,如果您在另一个类型中声明变量(示例中为 struct Foo),则“如果它们最初是在同一块中较早声明的”则不合格。

      所以答案就是将预先声明的变量设置为等于不使用 := 语法到值:

      ...
      var prev int
      prev, f.Bar = f.Bar, next
      ...
      

      【讨论】:

        【解决方案4】:

        只是您已经将 f 分配给 Foo f := Foo{100} 在这种情况下 f.Bar 是 100 所以要重新分配它只需删除列

        var prev string
        f := Foo{10}
        next := 11
        prev, f.Bar = f.Bar, next
        this will work
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-02-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多