Golang函数包含匿名作用域

问题描述:

有人可以给我一个关于何时和为什么我会在函数内使用匿名作用域的解释吗? (我不确定它实际上叫什么)。Golang函数包含匿名作用域

我一直在考虑一些旧的代码维护和某些功能含有这个“范围”之前,我还没有看到:

(简化了演示)

func DoSomething(someBoolValue bool) string { 
    if someBoolValue { 
     // do some stuff 
     return "yes" 
    } 
    { 
     // weird scope code 
    } 
    return "no" 
} 

我创建一个Go Playground来演示一些实际的代码(抛出一个错误)。

+1

如果您需要两个不同变量的相同标识符,即您可能会重新定义块中的someBoolValue:=“banana”,并且它仍然是该块之后的传入值,那么您可以使用它。 (在/ if/switch/select/func块内出现同样的范围,如其他答案所述) – Plato

它被称为变量范围和遮蔽:

转到使用块词法作用域:

1-的一个预声明标识符的范围是宇宙块。
2 - 在顶层(任何函数之外)声明的表示常量,类型,变量或 函数(但不是方法)的标识符的作用域是包块。
3 - 导入的 包的包名的范围是包含导入 声明的文件的文件块。
4-表示方法接收器,函数参数或结果变量的标识符的范围是函数体。
5-在函数 中声明的常量或变量标识符的范围从ConstSpec或VarSpec(ShortVarDecl,简称为 变量声明)的末尾开始,并在包含 块的最内层末尾结束。
6-在函数 中声明的类型标识符的范围从TypeSpec中的标识符开始,并在 最内层包含块的末尾处结束。在块中声明的标识符可以是在内部块中重新声明的 。虽然内部声明的标识符在范围内,但它表示内部声明所声明的实体。

包条款不是声明;软件包名称不在 出现在任何范围内。其目的是识别属于同一包的 的文件并指定用于导入 声明的默认包名。

你的工作示例代码:

package main 

import (
    "fmt" 
) 

func main() { 
    i := 10 
    { 
     i := 1 
     fmt.Println(i) // 1 
    } 
    fmt.Println(i) // 10 
} 

输出:

1 
10 

看:Where can we use Variable Scoping and Shadowing in Go?

{}在Go形成句法块。每个块定义一个新的范围。例如,这些是与iffor一起使用的相同块。

关于你的代码,我猜他们主要是为了可读性的目的。您可以重用或隐藏封闭范围中定义的变量,以便使用可能更清楚地声明代码意图的变量名称。

除此之外,它们也可以用于对一堆相关语句进行分组,也是为了便于阅读。

要了解他们的行为,请参阅@ Amd的答案。

+1

感谢您的回应。我认为他们可能在我的例子中被不必要地使用了,但我现在明白了他们的正确用法。 – danbondd