变量的定义
var a =1//编译器会推断变量 a的类型为int
b :=1 //短变量声明
var c int;c=1// 变量声明,并且赋值
变量的重声明
短变量声明。通过使用它,我们可以对同一个代码块中的变量进行重声明。
例子:
var err error
n, err := io.WriteString(os.Stdout, "Hello\n")//使用短变量声明对新变量n和旧变量err进行了“声明并赋值”,这也是对后者的重声明
变量重声明的前提条件
- 由于变量的类型在其初始化时就已经确定了,所以对它再次声明时赋予的类型必须与其原本
的类型相同,否则会产生编译错误。 - 变量的重声明只可能发生在某一个代码块中。如果与当前的变量重名的是外层代码块中的变
量,那么就是可重名变量了。 - 变量的重声明只有在使用短变量声明时才会发生,否则也无法通过编译。如果要在此处声明
全新的变量,那么就应该使用包含关键字var的声明语句,但是这时就不能与同一个代码块
中的任何变量有重名了 。 - 被“声明并赋值”的变量必须是多个,并且其中至少有一个是新的变量。这时我们才可以说
对其中的旧变量进行了重声明。
可重名变量
例子:
package main
import (
"fmt"
)
var str = "我在main外面"
func main() {
var str = "我在main里面"
{
str := "我在代码块内"
fmt.Println(str)
}
fmt.Println(str)
}
//输出的结果
//我在代码块内
//我在main里面
变量的查找:
-
首先,代码引用变量的时候总会最优先查找当前代码块中的那个变量。注意,这里的“当前
代码块”仅仅是引用变量的代码所在的那个代码块,并不包含任何子代码块。 -
其次,如果当前代码块中没有声明以此为名的变量,那么程序会沿着代码块的嵌套关系,从
直接包含当前代码块的那个代码块开始,一层一层地查找。 -
一般情况下,程序会一直查到当前代码包代表的那层代码块。如果仍然找不到,那么 Go 语
言的编译器就会报错了。 -
如果我们把代码包导入语句写成import . XXX的形式,那么就会让这个“XXX”包中公开的程序实体被当前源码文件中的代码,视为当前代码包中的程序实体。在查找当前源码文件不存在后,会查用这种方式导入的代码包
重名变量与变量重声明中的变量区别
-
变量重声明中的变量一定是在某一个代码块内的。注意,这里的“某一个代码块内”并不包
含它的任何子代码块,否则就变成了“多个代码块之间”。而重名变量指的正是在多个代
码块之间的由相同的标识符代表的变量。 -
变量重声明是对同一个变量的多次声明,这里的变量只有一个。而重名变量中涉及的变量
肯定是有多个的。 - 不论对变量重声明多少次,其类型必须始终一致,具体遵从它第一次被声明时给定的类型。
而重名变量之间不存在类似的限制,它们的类型可以是任意的。 - 如果重名变量所在的代码块之间存在直接或间接的嵌套关系,那么它们之间一定会存
在“屏蔽”的现象。但是这种现象绝对不会在变量重声明的场景下出现。
判断变量的类型
语法:
/*
类型断言表达式的语法形式是x.(T)。其中的x代表要被判断类型的那个值。这
个值当下的类型必须是接口类型的
*/
container := []string{"111", "222"}
// 需要将 container 转成接口类型,才可以使用类型推断(如果不是接口,那类型推断又有什么必要了)
value, ok := interface{}(container).([]string
/*
ok:将代表类型判断的结果bool类型
value:
ok=true:被判断的值将会被自动转换为[]string类型的值,并赋给变量value
ok=false:value将被赋予nil
*/
网友评论