文章目录
1.声明变量的方式
- var 变量名字 类型 = 表达式
- 短变量声明
2.Go语言的类型推断带来哪些好处?
Go 语言的类型推断可以明显提升程序的灵活性,使得代码重构变得更加容易,同时又不会给代码的维护带来额外负担(实际上,它恰恰可以避免散弹式的代码修改),更不会损失程序的运行效率。
3.变量重声明的前提条件
- 由于变量的类型在其初始化时就已经确定了,所以对它再次声明时赋予的类型必须与其原本 的类型相同,否则会产生编译错误。
- 变量的重声明只可能发生在某一个代码块中。如果与当前的变量重名的是外层代码块中的变 量,那么就是另外一种含义了。
- 变量的重声明只有在使用短变量声明时才会发生,否则也无法通过编译。如果要在此处声明 全新的变量,那么就应该使用包含关键字var的声明语句,但是这时就不能与同一个代码块中的任何变量有重名了。
- 被“声明并赋值”的变量必须是多个,并且其中至少有一个是新的变量。这时我们才可以说对其中的旧变量进行了重声明。
4.Go语言中查找变量的过程
首先,代码引用变量的时候总会最优先查找当前代码块中的那个变量。注意,这里的“当前代码块”仅仅是引用变量的代码所在的那个代码块,并不包含任何子代码块。 其次,如果当前代码块中没有声明以此为名的变量,那么程序会沿着代码块的嵌套关系,从 直接包含当前代码块的那个代码块开始,一层一层地查找。 一般情况下,程序会一直查到当前代码包代表的那层代码块。如果仍然找不到,那么Go语言的编译器就会报错了。(注意:如果我们把代码包导入语句写成import . XXX的形式(注意中间的那 个“.”),那么就会让这个“XXX”包中公开的程序实体被当前源码文件中的代码,视为当前代码包中的程序实体。)
5.不同代码块中的重名变量与变量重声明中的变量之间的区别
- 变量重声明中的变量一定是在某一个代码块内的。注意,这里的“某一个代码块内”并不包 含它的任何子代码块,否则就变成了“多个代码块之间”。而可重名变量指的正是在多个代 码块之间的由相同的标识符代表的变量。
- 变量重声明是对同一个变量的多次声明,这里的变量只有一个。而可重名变量中涉及的变量肯定是有多个的。
- 不论对变量重声明多少次,其类型必须始终一致,具体遵从它第一次被声明时给定的类型。 而可重名变量之间不存在类似的限制,它们的类型可以是任意的。
- 如果可重名变量所在的代码块之间存在直接或间接的嵌套关系,那么它们之间一定会存在“屏蔽”的现象。但是这种现象绝对不会在变量重声明的场景下出现。
6.类型断言表达式
类型断言表达式的形式:x.(T),其中x表示要被判断类型的值
7.类型转换规则中有哪些值得注意的地方?
- 类型转换的语法形式是T(x),其中x可以是一个变量也可以是表达式,如果是表达式,那么该表达式的结果只能是一个值而不能是多个值。
- 对于整数类型值、整数常量之间的类型转换,原则上只要源值在目标类型的可表示范围内 就是合法的。
- 虽然直接把一个整数值转换为一个string类型的值是可行的,但值得关注的是,被转换 的整数值应该可以代表一个有效的 Unicode 代码点,否则转换的结果将会是"�"
- 一个值在从string类型向[]byte类型转换时代表着以 UTF-8 编码的字符串会被拆分成零散、独立的字节
- 一个值在从string类型向[]rune类型转换时代表着字符串会被拆分成一个个 Unicode 字符
8.潜在类型中需要注意的地方
- 潜在类型的含义是 某个类型在本质上是哪个类型或者是哪个类型的集合
- 潜在类型相同的不同类型的值之间是可以进行类型转换的
- 即使两个类型的潜在类型相同,它们的值之间也不能进行判等或比较,它们的变量之间也不能赋值
9.类型定义与类型别名
类型别名编译时会被转成对应类型
类型别名可以同相同类型进行计算,自定义类型则不能
// 自定义类型
type MyInt int
// 类型别名
type IntAlias = int
var i MyInt = 0
var j IntAlias = 0
fmt.Printf("i MyInt %T %v\n", i, i) // 输出结果: i MyInt main.MyInt 0
fmt.Printf("j IntAlias %T %v\n", j, j) // 输出结果: j IntAlias int 0
10.思考题
(1)如果与当前的变量重名的是外层代码块中的变量,那么这意味着什么?
答:不意味着什么
package main
import "fmt"
var block = "1"
func main() {
block := "2"
{
block := "3"
fmt.Printf("The block is %s.\n", block)
}
fmt.Printf("The block is %s.\n", block)
}
(2)通过import . XXX这种导入代码包的方式导入的代码包中的变量与当前代码包中的变量重名了,那么 Go 语言是会把它们当做“可重名变量”看待还是会报错呢?
报错信息如下:
注意:如果我们把代码包导入语句写成import . XXX的形式(注意中间的那个“.”),那么就会让这个“XXX”包中公开的程序实体被当前源码文件中的代码,视为当前代码包中的程序实体。
(3)除了上述提及的那些,你还认为类型转换规则中有哪些值得注意的地方?
答:官方链接
(4)说说别名类型在代码重构过程中可以起到哪些作用吗?
答:类型别名是 Go 1.9 版本添加的新功能,主要用于解决代码升级、迁移中存在的类型兼容性问题。
最后本节涉及代码可以参考:demo GitHub地址