本节简单预览一下语言功能,有个相对完整的印象更利于学习后续知识。
源文件
- 源码文件使用 UTF-8 编码,对 Unicode 支持良好。
- 每个源文件都属于包的一部分,在文件头部用 package 声明所属包名称。
- 以“. Go”作为文件扩展名。
- 入口函数 main 没有参数,且必须放在 main 包中。
- 用 import 导入标准库或第三方包。请删除未使用的导入,否则编译器会将其当作错误。
- 可直接运行,或编译为可执行文件。
变量
- 使用 var 定义变量,支持类型推断。
- 基础数据类型划分清晰明确,有助于编写跨平台应用。
- 编译器确保变量总是被初始化为零值,避免出现意外状况。
- 在函数内部,还可省略 var 关键字,使用更简单的定义模式:
:=
- 编译器将未使用的局部变量定义当作错误。
表达式
Go 仅有三种流控制语句,与大多数语言相比,都可称得上简单。
- if-else
- switch-case
- for/for-range
函数
- 函数可定义多个返回值,甚至对其命名。
- 函数是第一类型(第一公民),可作为参数或返回值。
- 用 defer 定义延迟调用,无论函数是否出错,它都确保结束前被调用。
数据
- 切片(slice)可实现类似动态数组的功能。
- 将字典(map)类型内置,可直接从运行时层面获得性能优化。
- 所谓 ok-idiom 模式,是指在多返回值中用一个名为 ok 的布尔值来标示操作是否成功。因为很多操作默认返回零值,所以须额外说明。
package main
import(
"fmt"
)
func main() {
m:=make(map[string]int) // 创建字典类型对象
m["a"] =1 // 添加或设置
x,ok:=m["b"] // 使用ok-idiom获取值,可知道key/value是否存在
fmt.Println(x,ok)
delete(m, "a") // 删除
}
- 结构体(struct)可匿名嵌入其他类型。
package main
type user struct{ // 结构体类型
name string
age byte
}
type manager struct{
user // 匿名嵌入其他类型
title string
}
func main() {
var m manager
m.name= "Tom" // 直接访问匿名字段的成员
m.age=29
m.title= "CTO"
}
方法
- 可以为当前包内的任意类型定义方法。
- 还可直接调用匿名字段的方法,这种方式可实现与继承类似的功能。
package main
import(
"fmt"
)
type user struct {
name string
age byte
}
func (u user) ToString() string {
return fmt.Sprintf("%+v", u)
}
type manager struct {
user
title string
}
func main() {
var m manager
m.name = "Tom"
m.age = 29
println(m.ToString()) // 调用user.ToString()
}
接口
- 接口采用了 duck type 方式,也就是说无须在实现类型上添加显式声明。(只要包含接口所需的全部方法,即表示实现了该接口)
- 另有空接口类型
interface{}
,用途类似 OOP 里的system.Object
,可接收任意类型对象。
并发
- 整个运行时完全并发化设计。凡你能看到的,几乎都在以 goroutine 方式运行。
- 这是一种比普通协程或线程更加高效的并发设计,能轻松创建和运行成千上万的并发任务。
- 通道(channel)与 goroutine 搭配,实现用通信代替内存共享的 CSP 模型。