# 1.7 变量和声明
这将是美好的开始和结束,通过写下`x = 4`,我们查看变量,可以说声明了一个变量并赋值,但是很不幸,go语言变量声明和赋值比这更复杂。通过学习一些简单的示例开始学习变量声明和赋值。然后在下一章,当我们创建并使用结构体时,我们会深入学习。尽管如此,你需要花一些时间去适应。
你可能会惊讶,为什么会如此复杂,让我们以一些例子开始学习。
在go中最直接的方式去声明变量并赋值也是最繁琐的:
```go
package main
import (
"fmt"
)
func main() {
var power int
power = 9000
fmt.Printf("It's over %d\n", power)
}
```
在这里我们声明了一个`int`型变量`power`。默认情况下,go会给`power`赋一个`0`值。整型赋`0`,布尔型赋`false`,字符串型赋`""`等。然后,我们将`9000`赋值给变量`power`。我们也可以将2行代码合并成一行:
`var power int = 9000`
虽然需要输入很多。go有一种方便简洁的变量声明操作符:`:=`,go可以推断变量的类型:
`power := 9000`
这里有一个简洁的写法,通过函数也能正常工作:
```go
func main() {
power := getPower()
}
func getPower() int {
return 9001
}
```
这里需要谨记,`:=`用于声明一个变量并给变量赋值。为什么会这样?因为一个变量不能被声明2次(不在相同的代码范围)。如果你试着运行下面代码,你将会得到一个错误信息。
```go
func main() {
power := 9000
fmt.Printf("It's over %d\n", power)
// COMPILER ERROR:
// no new variables on left side of :=
power := 9001
fmt.Printf("It's also over %d\n", power)
}
```
编译器会提示`:=`左边不是一个新变量。这意味着当我们第一次声明变量时,我们使用`:=`。但是在随后的赋值,我们要使用`=`。这有很多意义,但这也随时提醒着你何时该使用`:=`和`=`。
如果你仔细阅读错误信息,你将发现有多个变量。因为go支持多个变量同时赋值(使用`=`或者`:=`):
```go
func main() {
name, power := "Goku", 9000
fmt.Printf("%s's power is over %d\n", name, power)
}
```
另外,如果一个变量是新变量也可以使用`:=`进行赋值。例如:
```go
func main() {
power := 1000
fmt.Printf("default power is %d\n", power)
name, power := "Goku", 9000
fmt.Printf("%s's power is over %d\n", name, power)
}
```
尽管变量`power`使用了`:=`,但是编译器不会在第2次使用`:=`时报错,因为这里有一个变量`name`,这是一个新的变量,允许使用`:=`。但是你不能改变`power`的类型。它已经被声明成一个整型,只能赋值整数。
现在,需要知道的最后一件事是,类似包导入,go程序中不能存在未使用的变量,例如:
```go
func main() {
name, power := "Goku", 1000
fmt.Printf("default power is %d\n", power)
}
```
这段代码不能编译,因为变量`name`已经声明,但是没有被使用。类似未使用的导入包,可能这会让你有点失望,但是总的来看,我认为这是为了让代码更加的简洁和具有可读性。
接下来不在介绍关于变量的声明和赋值相关内容了。现在,你只需要记住使用`var NAME TYPE`声明一个变量,并且变量的初始值为它相应类型的零值,使用`NAME := VALUE`声明一个变量并赋值,使用`NAME = VALUE`去给已经声明过的变量赋值。
## 链接
- 关于本书
- 引言
- 准备工作
- 安装开发环境
- 开始使用Go
- 创建一个Go模块
- 第1章:基础知识
- 1.1 编译
- 1.2 静态类型
- 1.3 类c语法
- 1.4 垃圾回收
- 1.5 运行go代码
- 1.6 导入包
- 1.7 变量和声明
- 1.8 函数声明
- 1.9 继续之前
- 第2章:语法学习
- 2.1 声明和初始化
- 2.2 结构体上的函数
- 2.3 构造函数
- 2.4 new
- 2.5 结构体字段
- 2.6 组合
- 2.7 指针类型和值类型
- 2.8 继续之前
- 第3章:复杂类型
- 3.1 数组
- 3.2 切片
- 3.3 映射
- 3.4 指针类型和值类型
- 3.5 继续之前
- 第4章:面向对象
- 4.1 包
- 4.2 接口
- 4.3 继续之前
- 第5章:综合知识
- 5.1 错误处理
- 5.2 defer
- 5.3 go语言风格
- 5.4 初始化的if
- 5.5 空接口和转换
- 5.6 字符串和字节数组
- 5.7 函数类型
- 5.8 内存分配
- 第6章:高并发
- 6.1 go协程
- 6.2 同步
- 6.3 通道
- 6.4 继续之前
- 第7章:工具库
- 7.1 类型转换
- 7.2 时间操作
- 第8章:程序测试
- 单元测试
- 性能测试
- 第9章:简单实例
- 内存分配
- 第10章:项目实战
- 结论
- 附录