本节简单预览一下语言功能,有个相对完整的印象更利于学习后续知识。

源文件

  • 源码文件使用 UTF-8 编码,对 Unicode 支持良好。
  • 每个源文件都属于包的一部分,在文件头部用 package 声明所属包名称。
  • 以“. Go”作为文件扩展名。
  • 入口函数 main 没有参数,且必须放在 main 包中。
  • 用 import 导入标准库或第三方包。请删除未使用的导入,否则编译器会将其当作错误。
  • 可直接运行,或编译为可执行文件。

变量

  • 使用 var 定义变量,支持类型推断。
  • 基础数据类型划分清晰明确,有助于编写跨平台应用。
  • 编译器确保变量总是被初始化为零值,避免出现意外状况。
  • 在函数内部,还可省略 var 关键字,使用更简单的定义模式::=
  • 编译器将未使用的局部变量定义当作错误。

表达式

Go 仅有三种流控制语句,与大多数语言相比,都可称得上简单。

  1. if-else
  2. switch-case
  3. 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 模型。