英文:
Golang shadowing behavior explanation
问题
在这段代码中,
list := []string{"a", "b", "c"}
for {
list := repeat(list)
...
func repeat(list []string) []string {
...
很明显,作为repeat()
函数参数的list
变量是外部的、被遮蔽的list
变量。现在我的问题是,Go语言的专家会如何解释这种行为?乍一看,我以为内部list
变量的声明会在repeat(list)
表达式求值之前进行。
英文:
In this snippet
list := []string{"a", "b", "c"}
for {
list := repeat(list)
...
func repeat(list []string) []string {
...
it is clear that list
variable used as the argument to repeat()
function is the outer, shadowed list variable. Now my question is, how would a Go language lawyer explain this behaviour? At first glance, I thought the declaration of the inner list variable would have preceded the repeat(list)
expression evaluation.
答案1
得分: 4
Go使用块进行词法作用域。在这个例子中:
list := []string{"a", "b", "c"}
for {
list := repeat(list)
第二个list
在for块内遮蔽了第一个list
,并且不会改变外部的list
变量。
因为在内部list
声明和赋值之前,repeat
的参数被求值,所以repeat
接收的是外部list
的值。
英文:
Go is lexically scoped using blocks. In this example:
list := []string{"a", "b", "c"}
for {
list := repeat(list)
The second list
shadows the first within the for block, and doesn't alter the outer list
variable.
Because the arguments to repeat
are evaluated before the inner list
is declared and assigned, repeat
receives the value from the outer list
答案2
得分: 1
在SO上的人们确实很苛刻。我正在寻找的答案基本上是,在语句中:
list := repeat(list)
内部的list变量在语句结束之前不在作用域内,而外部的list变量在作用域内。这是规范中的说明:
> Go使用块进行词法作用域:
>
> 预声明标识符的作用域是全局块。在顶层(任何函数之外)声明的常量、类型、变量或函数(但不包括方法)的标识符的作用域是包块。导入包的包名的作用域是包含导入声明的文件块。方法接收器、函数参数或结果变量的标识符的作用域是函数体。**在函数内部声明的常量或变量标识符的作用域从ConstSpec或VarSpec(对于短变量声明为ShortVarDecl)的结束开始,直到最内层包含块的结束。**在函数内部声明的类型标识符的作用域从TypeSpec中的标识符开始,直到最内层包含块的结束。
我在第一次阅读时忽略了这段突出显示的文字,这是我犯的错误。对不起。
英文:
It's a tough crowd on SO. The answer I was looking for was essentially that in the statement:
list := repeat(list)
the inner list variable is not in scope until the end of the statement whereas the outer list variable is in scope. Here's what the spec has to say:
> Go is lexically scoped using blocks:
>
> The scope of a predeclared identifier is the universe block. The scope
> of an identifier denoting a constant, type, variable, or function (but
> not method) declared at top level (outside any function) is the
> package block. The scope of the package name of an imported package is
> the file block of the file containing the import declaration. The
> scope of an identifier denoting a method receiver, function parameter,
> or result variable is the function body. The scope of a constant or
> variable identifier declared inside a function begins at the end of
> the ConstSpec or VarSpec (ShortVarDecl for short variable
> declarations) and ends at the end of the innermost containing block.
> The scope of a type identifier declared inside a function begins at
> the identifier in the TypeSpec and ends at the end of the innermost
> containing block.
The highlighted text is the operational rationale that I missed in the first read. Mea culpa.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论