## 8.2\. 语法
Go中变量的声明语法和C++相反。定义变量时,先写变量的名字,然后是变量的类型。这样 不会出现像C++中, 类型不能匹配后面所有变量的情况(指针类型)。而且语法清晰,便于 阅读。
```
Go C++
var v1 int // int v1;
var v2 string // const std::string v2; (approximately 近似等价)
var v3 [10]int // int v3[10];
var v4 []int // int* v4; (approximately 近似等价)
var v5 struct { f int } // struct { int f; } v5;
var v6 *int // int* v6; (but no pointer arithmetic 没有指针算术)
var v7 map[string]int // unordered_map<string, int>* v7; (approximately 近似等价)
var v8 func(a int) int // int (*v8)(int a);
```
变量的声明通常是从某些关键字开始,例如var, func,const或type。对于类型的专有方法定义, 在变量名前面还要加上对应该方法发类型对象变量,细节清参考discussion of interfaces。
你也可以在关键字后面加括号,这样可以同时定义多个变量。
```
var (
i int
m float
)
```
When declaring a function, you must either provide a name for each parameter or not provide a name for any parameter; you can't omit some names and provide others. You may group several names with the same type:
定义函数的时候,你可以指定每个参数的名字或者不指定任何参数名字,但是你不能只指定部分函数参数的 名字。如果是相邻的参数是相同的类型,也可以统一指定类型。
```
func f(i, j, k int, s, t string)
```
对于变量,可以在定时进行初始化。对于这种情况,我们可以省略变量的类型部分,因为Go编译器 可以根据初始化的值推导出变量的类型。
```
var v = *p
```
如果变量定义时没有初始化,则必须指定类型。没有显式初始化的变量,会被自动初始化为空的值, 例如0,nil等。Go不存在完全未初始化的变量。
用:=操作符,还有更简短的定义语法:
```
v1 := v2
```
和下面语句等价:
```
var v1 = v2
```
Go还提供多个变量同时赋值:
```
i, j = j, i // Swap i and j.
```
函数也可以返回多个值,多个返回值需要用括号括起来。返回值可以用一个等于符号赋给 多个变量。
```
func f() (i int, j int) { ... }
v1, v2 = f()
```
Go中使用很少的分号,虽然每个语句之间实际上是用分号分割的。因为,go编译器会在看似 完整的语句末尾自动添加分号(具体细节清参考Go语言手册)。 当然,自动添加分号也可能带来一些问题。例如:
```
func g()
{ // INVALID
}
```
在g()函数后面会被自动添加分号,导致函数编译出错。下面的代码也有类似的 问题:
```
if x {
}
else { // INVALID
}
```
在第一个花括号}的后面会被自动添加分号,导致else语句 出现语法错误。
分号可以用来分割语句,你仍然可以安装C++的方式来使用分号。不过Go语言中,常常省略不 必要的分号。 只有在 循环语句的初始化部分,或者一行写多个语句的时候才是必须的。
继续前面的问题。我们并不用担心因为花括号的位置导致的编译错误,因此我们可以用 gofmt 来排版程序代码。 gofmt 工具总是可以将代码排版成统一的风格。While the style may initially seem odd, it is as good as any other style, and familiarity will lead to comfort.
当用指针访问结构体的时候,我们用.代替->语法。 因此,用结构体类型和结构体指针类型访问结构体成员的语法是一样的。
```
type myStruct struct { i int }
var v9 myStruct // v9 has structure type
var p9 *myStruct // p9 is a pointer to a structure
f(v9.i, p9.i)
```
Go不要求在if语句的条件部分用小括弧,但是要求if后面的代码 部分必须有花括弧。类似的规则也适用于for和switch等语句。
```
if a < b { f() } // Valid
if (a < b) { f() } // Valid (condition is a parenthesized expression)
if (a < b) f() // INVALID
for i = 0; i < 10; i++ {} // Valid
for (i = 0; i < 10; i++) {} // INVALID
```
Go语言中没有while和do/while循环语句。我们可以用只有一个 条件语句的for来代替while循环。如果省略for 的条件部分,则是一个无限循环。
Go增加了带标号的break 和continue语法。不过标号必须 是针对for,switch或select代码段的。
对于switch语句,case匹配后不会再继续匹配后续的部分。 对于没有任何匹配的情况,可以用fallthrough 语句。
```
switch i {
case 0: // empty case body
case 1:
f() // f is not called when i == 0!
}
```
case语句还可以带多个值:
```
switch i {
case 0, 1:
f() // f is called if i == 0 || i == 1.
}
```
case语句不一定必须是整数或整数常量。如果省略switch的 要匹配的值,那么case可以是任意的条件语言。
```
switch {
case i < 0:
f1()
case i == 0:
f2()
case i > 0:
f3()
}
```
++ 和 -- 不再是表达式,它们只能在语句中使用。因此, c = *p++ 是错误的。语句 *p++ 的含义也完全不同,在go中等价于 (*p)++ 。
defer可以用于指定函数返回前要执行的语句。
```
fd := open("filename")
defer close(fd) // fd will be closed when this function returns.
```
- 1. 关于本文
- 2. Go语言简介
- 3. 安装go环境
- 3.1. 简介
- 3.2. 安装C语言工具
- 3.3. 安装Mercurial
- 3.4. 获取代码
- 3.5. 安装Go
- 3.6. 编写程序
- 3.7. 进一步学习
- 3.8. 更新go到新版本
- 3.9. 社区资源
- 3.10. 环境变量
- 4. Go语言入门
- 4.1. 简介
- 4.2. Hello,世界
- 4.3. 分号(Semicolons)
- 4.4. 编译
- 4.5. Echo
- 4.6. 类型简介
- 4.7. 申请内存
- 4.8. 常量
- 4.9. I/O包
- 4.10. Rotting cats
- 4.11. Sorting
- 4.12. 打印输出
- 4.13. 生成素数
- 4.14. Multiplexing
- 5. Effective Go
- 5.1. 简介
- 5.2. 格式化
- 5.3. 注释
- 5.4. 命名
- 5.5. 分号
- 5.6. 控制流
- 5.7. 函数
- 5.8. 数据
- 5.9. 初始化
- 5.10. 方法
- 5.11. 接口和其他类型
- 5.12. 内置
- 5.13. 并发
- 5.14. 错误处理
- 5.15. Web服务器
- 6. 如何编写Go程序
- 6.1. 简介
- 6.2. 社区资源
- 6.3. 新建一个包
- 6.4. 测试
- 6.5. 一个带测试的演示包
- 7. Codelab: 编写Web程序
- 7.1. 简介
- 7.2. 开始
- 7.3. 数据结构
- 7.4. 使用http包
- 7.5. 基于http提供wiki页面
- 7.6. 编辑页面
- 7.7. template包
- 7.8. 处理不存在的页面
- 7.9. 储存页面
- 7.10. 错误处理
- 7.11. 模板缓存
- 7.12. 验证
- 7.13. 函数文本和闭包
- 7.14. 试试!
- 7.15. 其他任务
- 8. 针对C++程序员指南
- 8.1. 概念差异
- 8.2. 语法
- 8.3. 常量
- 8.4. Slices(切片)
- 8.5. 构造值对象
- 8.6. Interfaces(接口)
- 8.7. Goroutines
- 8.8. Channels(管道)
- 9. 内存模型
- 9.1. 简介
- 9.2. Happens Before
- 9.3. 同步(Synchronization)
- 9.4. 错误的同步方式
- 10. 附录
- 10.1. 命令行工具
- 10.2. 视频和讲座
- 10.3. Release History
- 10.4. Go Roadmap
- 10.5. 相关资源