编程语言都是相通的,所以通过记录与其他语言不同的部分学习Go语言。

Reference: Go 语言教程

Go基础语法

1、当标识符(包括常量、变量、类型、函数名、结构字段等等)以一个大写字母开头,如:Group1,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(客户端程序需要先导入这个包),这被称为导出(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )

2、需要注意的是 { 不能单独放在一行,所以以下代码在运行时会产生错误:

1
2
3
4
5
6
7
8
package main

import "fmt"

func main() 
{ // 错误,{ 不能在单独的行上
  fmt.Println("Hello, World!")
}

3、在 Go 程序中,一行代表一个语句结束。每个语句不需要像 C 家族中的其它语言一样以分号 ; 结尾,因为这些工作都将由 Go 编译器自动完成。

如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分,但在实际开发中我们并不鼓励这种做法。

Go语言变量

Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。

声明变量的一般形式是使用 var 关键字:

1
var identifier type

可以一次声明多个变量:

1
var identifier1, identifier2 type

声明新的变量, := 是一个声明语句。

intVal := 1 相等于:

1
2
var intVal int 
intVal =1 

可以将 var f string = “Runoob” 简写为 f := “Runoob”

常量的定义格式:

1
const identifier [type] = value

Go语言数组

数组初始化:

1
var balance = [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

也可以通过字面量在声明数组的同时快速初始化数组:

1
balance := [5]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

如果数组长度不确定,可以使用 代替数组的长度,编译器会根据元素个数自行推断数组的长度:

1
2
3
var balance = [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}
balance := [...]float32{1000.0, 2.0, 3.4, 7.0, 50.0}

如果设置了数组的长度,还可以通过指定下标来初始化元素:

1
2
//  将索引为 1 和 3 的元素初始化
balance := [5]float32{1:2.0,3:7.0}

Go语言切片(Slice)

Go 语言切片是对数组的抽象。

Go 数组的长度不可改变,在特定场景中这样的集合就不太适用,Go 中提供了一种灵活,功能强悍的内置类型切片(“动态数组”),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

定义切片

你可以声明一个未指定大小的数组来定义切片:

1
var identifier []type

切片不需要说明长度。

或使用 make() 函数来创建切片:

1
2
3
4
5
var slice1 []type = make([]type, len)

也可以简写为

slice1 := make([]type, len)

也可以指定容量,其中 capacity 为可选参数。

1
make([]T, length, capacity)

这里 len 是数组的长度并且也是切片的初始长度。

切片初始化

1
s :=[] int {1,2,3 } 

直接初始化切片,[] 表示是切片类型,{1,2,3} 初始化值依次是 1,2,3,其 cap=len=3

1
s := arr[:] 

初始化切片 s,是数组 arr 的引用。

1
s := arr[startIndex:endIndex] 

将 arr 中从下标 startIndex 到 endIndex-1 下的元素创建为一个新的切片。

1
s := arr[startIndex:] 

默认 endIndex 时将表示一直到arr的最后一个元素。

1
s := arr[:endIndex] 

默认 startIndex 时将表示从 arr 的第一个元素开始。

1
s1 := s[startIndex:endIndex] 

通过切片 s 初始化切片 s1。

1
s :=make([]int,len,cap) 

通过内置函数 make() 初始化切片s[]int 标识为其元素类型为 int 的切片。

Go语言范围(Range)

Go 语言中 range 关键字用于 for 循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素。在数组和切片中它返回元素的索引和索引对应的值,在集合中返回 key-value 对。

for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:

1
2
3
for key, value := range oldMap {
    newMap[key] = value
}

以上代码中的 key 和 value 是可以省略。

如果只想读取 key,格式如下:

1
for key := range oldMap

或者这样:

1
for key, _ := range oldMap

如果只想读取 value,格式如下:

1
for _, value := range oldMap

定义 Map

可以使用内建函数 make 也可以使用 map 关键字来定义 Map:

1
2
3
4
5
/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type

/* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)

如果不初始化 map,那么就会创建一个 nil map。nil map 不能用来存放键值对。

Go 错误处理

Go 语言通过内置的错误接口提供了非常简单的错误处理机制。

error类型是一个接口类型,定义:

1
2
3
type error interface {
    Error() string
}

可以在编码中通过实现 error 接口类型来生成错误信息。

函数通常在最后的返回值中返回错误信息。使用errors.New 可返回一个错误信息。

Go 并发

Go 语言支持并发,我们只需要通过 go 关键字来开启 goroutine 即可。

goroutine 是轻量级线程,goroutine 的调度是由 Golang 运行时进行管理的。

goroutine 语法格式:

1
go 函数名( 参数列表 )

通道(channel)

通道(channel)是用来传递数据的一个数据结构。

通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。操作符 <- 用于指定通道的方向,发送或接收。如果未指定方向,则为双向通道。

1
2
3
ch <- v    // 把 v 发送到通道 ch
v := <-ch  // 从 ch 接收数据
           // 并把值赋给 v

声明一个通道很简单,我们使用chan关键字即可,通道在使用前必须先创建:

1
ch := make(chan int)

注意:默认情况下,通道是不带缓冲区的。发送端发送数据,同时必须有接收端相应的接收数据。