问题:声明变量有几种方式?
var name = *flag.String("name", "everyone", "The greeting object.")//第一种
name := *flag.String("name", "everyone", "The greeting object.")//第二种
解析:
Go 语言中的类型推断:一种编程语言在编译期自动解释表达式类型的能力
短变量声明的用法:只能在函数体内部使用短变量声明
Go 语言的类型推断可以带来哪些好处?
Go 语言的类型推断可以明显提升程序的灵活性,使得代码重构变得更加容易,同时又不会给代码的维护带来额外负担,更不会损失程序的运行效率。
变量的重声明(已经声明过的变量再次声明)是什么意思?
- 由于变量的类型在其初始化时就已经确定了,所以对它再次声明时赋予的类型必须与其原本的类型相同,否则会产生编译错误。
- 变量的重声明只可能发生在某一个代码块中。如果与当前的变量重名的是外层代码块中的变量,那么就是另外一种含义了
- 变量的重声明只有在使用短变量声明时才会发生,否则也无法通过编译。
- 被“声明并赋值”的变量必须是多个,并且其中至少有一个是新的变量。这时我们才可以说对其中的旧变量进行了重声明。
问题:如果一个变量与其外层代码块中的变量重名会出现什么状况?
var block = "package"//声明
func main() {
block := "function"//再声明
{
block := "inner"//再声明
fmt.Printf("The block is %s.\n", block)
}
fmt.Printf("The block is %s.\n", block)
}
解析:
程序实体的访问权限有三种:包级私有的、模块级私有的和公开的。
能通过编译。运行后打印出的内容是:
The block is inner. The block is function.
- 首先,代码引用变量的时候总会最优先查找当前代码块中的那个变量
- 其次,如果当前代码块中没有声明以此为名的变量,那么程序会沿着代码块的嵌套关系,从直接包含当前代码块的那个代码块开始,一层一层地查找
- 一般情况下,程序会一直查到当前代码包代表的那层代码块
不同代码块中的重名变量与变量重声明中的变量区别到底在哪儿?
- 变量重声明中的变量一定是在某一个代码块内的。(某一个代码块内”并不包含它的任何子代码块)
- 而可重名变量指的正是在多个代码块之间的由相同的标识符代表的变量。
- 变量重声明是对同一个变量的多次声明,这里的变量只有一个。而可重名变量中涉及的变量肯定是有多个的
- 不论对变量重声明多少次,其类型必须始终一致,具体遵从它第一次被声明时给定的类型。而可重名变量之间不存在类似的限制,它们的类型可以是任意的
- 如果可重名变量所在的代码块之间存在直接或间接的嵌套关系,那么它们之间一定会存在“屏蔽”的现象。但是这种现象绝对不会在变量重声明的场景下出现。