为什么在golang中只初始化定义中的一个变量会失败

问题描述 投票:0回答:2

在使用以下签名调用库函数时:

func New() (*sql.DB, Sqlmock, error)

像这样:

suite.db, suite.mock, err := sqlmock.New() // inside a suite method

我收到错误

expected identifier on left side of :=

但是,当我改变这个

var err error
suite.db, suite.mock, err = sqlmock.New()

错误消失了!为什么在:=赋值中声明k <n个变量失败?!

go
2个回答
3
投票

:=不是assignment,它是short variable declaration。作业使用例如简单的=运算符。

顾名思义:它是声明变量。 suite.db不是变量,它是expression,更具体地说是primary expression;确切地说是selector

短变量声明使用以下语法:

ShortVarDecl = IdentifierList ":=" ExpressionList .

IdentifierList在哪里:

IdentifierList = identifier { "," identifier } .

所以你必须列出identifiers。对此“声明新变量规则”的一个“例外”是重新声明:

与常规变量声明不同,短变量声明可以重新声明变量,前提是它们最初在同一个块中声明(或者如果块是函数体的参数列表)具有相同类型,并且至少有一个非blank变量是新的。因此,重新声明只能出现在多变量简短声明中。重新声明不会引入新变量;它只是为原始分配一个新值。

因此,如果在同一个块中声明它们,则允许在短变量声明中使用现有变量,并且还提供新标识符(不仅仅是现有变量 - 在这种情况下,您必须使用赋值)。

见相关:Why there are two ways of declaring variables in Go, what's the difference and which to use?

当您声明err之前并将:=更改为=时,它可以工作,因为赋值不需要赋值运算符左侧的标识符,而是表达式:

Assignment = ExpressionList assign_op ExpressionList .

如上所述,suite.db是一个表达式,就像现有变量(标识符)一样。


4
投票

:=声明了一个新的变量“identifier”。这意味着您在程序中添加了一个可以赋值的命名对象。结构的字段已经被命名,因为在golang解析器中知道它们存在,因此在这种情况下使用:=对golang没有意义。

为什么在:=赋值中声明k <n个变量失败?!

我不确定“k <n”是什么意思,但我认为你的意思是“为什么在:=的左侧有多个变量失败?”。如果这就是你的意思,那不是真的。

x, y, z := func() (int,int,int) {return 1,2,3}()
fmt.Println(x, y, z)

工作得很好。问题是golang不能为struct字段创建“标识符”(也就是新命名的变量),因为该struct字段已经存在。

编辑:我只是有一个脑波,你可能有意思“为什么只有一些新的标识符在:=的左侧声明不起作用?”。这也不是真的。

x, y := 5, 6
fmt.Println(x, y)
x, y, z := 1, 2, 3
fmt.Println(x, y, z)

以上工作也很好。

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