Golang的遮蔽行为解释

huangapple go评论85阅读模式
英文:

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中的标识符开始,直到最内层包含块的结束。

我在第一次阅读时忽略了这段突出显示的文字,这是我犯的错误。对不起。 Golang的遮蔽行为解释

英文:

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. Golang的遮蔽行为解释

huangapple
  • 本文由 发表于 2015年11月7日 01:08:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/33572004.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定