[Golang学习笔记] 05 程序实体2 作用域访问权限和变量重声明

作用域访问权限:

程序实体访问权限(作用域)有三种:
1. 包级私有(代码包)
2. 模块级私有(代码包)
3. 公开(全域)。

一个函数是一个代码块。
一个程序实体的作用域总是会被限制在某个代码块中。
好处:控制访问权限, 对“高内聚,低耦合”思想的实践。

面试题:如果一个变量与其外层代码块中的变量重名会出现什么状况?

package main

import "fmt"

var block = "package"

func main() {
    block := "function"
    {
        block := "inner"
        fmt.Printf("The block is %s.
", block)
    }
    fmt.Printf("The block is %s.
", block)
}

上面代码能通过编译。运行后打印内容:

The block is inner.
The block is function.

解析:

对于不同的代码块,变量重名没有什么大不了,照样可以通过编译。
1. 代码引用变量的时候总会最优先查找当前那个变量。“当前代码块”仅仅是引用变量的代码所在的那个代码块,并不包含任何子代码块。
2. 如果当前代码块中没有声明以此为名的变量,程序会沿着代码块的嵌套关系,从直接包含当前代码块的那个代码块开始,一层一层地查找。

查找过程:从小作用域到大作用域

典型回答:
如果变量重名,在全域代码块中声明的变量会被子代码块中的重声明覆盖。

在子代码块中声明的变量,只能在该代码块中生效,使用。

重声明:

Q:不同代码块中的重命名变量与变量重声明中的变量区别在哪儿?
1. 变量重声明的变量一定在某一个代码块内。不包含它的任何子代码块。
2. 变量重声明是对同一个变量的多次声明,变量只有一个。而可重命名变量中涉及的变量肯定是有多个的。
3. 不论对变量重声明多少次,其类型必须始终一致。具体遵从第一次被声明时给定的类型。而可重命名变量无此限制。
4. 可重命名变量在代码块之间,存在直接或间接的嵌套关系,存在“屏蔽”的现象。

 

思考题:如果通过import . xxx 这种导入代码包中的变量与当前代码包中的变量重名了,那么Go语言是会把他们当做“可重名变量”看待还是会编译报错呢?

A:会报redeclared错误。(变量名大写)
采用import . xxx,会认为引入的代码包的代码,如果在本包中一样,那作用域其实时同一个,不允许重复声明。

 本学习笔记是仅为了总结自己学到的Go语言核心知识,方便以后回忆,文中部分内容摘录自极客时间的《Go语言核心36讲》专栏,如有侵权,请联系我删除。

 

原文地址:https://www.cnblogs.com/fyql/p/10202358.html