Go语言学习笔记

最近在公司实习,项目中需要用到Golang,所以花一些时间来自学一下。因为以前有C/C++基础,所以学起来不是太吃力。现将学习的语法简单记录如下,如果要深究详细的语法细节,请参考相关的Go语言书籍:

最近在折腾博客的markdown和代码排版及高亮插件,还没找到一个合适的,所以这篇文章的格式有点乱,望理解!不过,我们看的是知识嘛!对不?

  1. Go的源程序文件是以.go结尾的文件,其一般有以下几个组成部分:
  • 包声明:每个包的起始部分都要声明该包的名称,最常见的是package main

  • 引入包:相当于C中的include,需要包含一些库,常见的是标准输入输出相关的库fmt:import "fmt"

  • 函数:所有编程语言中都有函数的概念,为完成某一功能的一段代码的集合。Go中的函数写法如下:

1
2
3
4
func Add(x,y int)(res int,err error){
res=x+y
return res,err
}

如以上所示,函数可以返回多个返回值(res和err)。

  • 变量:编程语言离不开变量,其实变量就是一块内存空间的名字。变量的常见定义如下:
1
var a int :=10

var表示这是一个变量,int为变量类型,而变量名称放在var和类型中间。

值得注意的是,Go语言中没有private,protected,public,static等关键字,所以用变量的大小写来控制变量的可见性。如果变量名或函数名的第一个字母是大写,则该变量在外部包中可见,否则不可见。

可以使用一个形如a:=10的语句来定义一个变量,称为初始化声明,编译器会自动推断a是一个变量,且类型为int。

  • 语句 & 表达式

  • 注释:注释和C/C++并无二致。

  1. 运行:写好代码并检查无误后,可以用go run test.go命令来运行,也可以用go build先编译,再执行。

  2. Go语言中的数据类型有如下几种:

  • 布尔型:其值可取true或者false,代表真和假

  • 数字类型:包括整数,浮点数和复数类型

  • 字符串类型:由单个字符组成的字符序列,采用Unicode编码,因此可在字符串中使用中文等非ASCII字符。

  • 派生类型:包括以下几种:

    *   指针
    
    *   数组
    
    *   结构体
    
    *   联合体
    
    *   函数
    
    *   切片
    
    *   接口
    
    *   Map类型
    
    *   Channel类型
    
  1. 常量
  • 常量即在程序运行时不会被修改的量,它也有类型,但只能是布尔型,数字型和字符串型。

  • 可以通过const关键字给常量一个名称,比如const a int = 10,其中int可以省略,编译器会自动推导。

  • 常量还可以用作枚举,如下:

1
2
3
4
5
const (
one=1
two=2
three=3
}
  • iota是一个特殊的常量,它在程序中每遇到const就重置为0,遇到另一个iota就由编译器加1。
  1. 运算符

Go语言的运算符和C/C++中基本保持一致,只有按位取反运算符不是~而是^

  1. 条件语句

Go语言的条件语句有if,else,switch,select,重点说说switch和select。

switch格式和C/C++一致,但Go中每次case执行完成后,即使没有break,也不会顺序执行下一条,除非显式指定。

case后面的值也不限定在整数范围之内,可以是任意类型。并且可以同时测定多个值,如下:

1
2
3
4
5
6
7
8
var str string = "Hello world"
var a int = 10
switch {
case str == "Hello world", a == 10:
fmt.Println("hello world!")
case str == "smart", a == 10:
fmt.Println("smart!")
}

select类似于用于通信的switch语句,每个case必须是一个通信操作,要么发送要么接收。select随机执行一个可执行的case,如果没有case可执行,select将阻塞,直到有case可执行。

  1. 循环语句

    Go语言只提供了for循环语句,没有C/C++中的while或者do…while循环。

    对比一下C/C++和Go中死循环的写法,Go显得简洁而优雅:

  2. 函数

    函数的语法已经在上面写过,要注意的是,函数的参数传递有两种形式:值传递和引用传递。在Go中,数组也是作为值传递的。

  3. 数组

    声明一个含有10个元素的整形数组的语句如下:

1
var arr [10] int

声明一个含有10个元素的整形数组并初始化的语句如下:

1
var arr [10] int = [10] int {1,2,3,4,5,6,7,8,9,0}
  1. 指针

    一个指向整形空间的指针的声明如下:

1
var ptr *int
  1. 切片

通过定义一个不指定大小的数组来定义切片并初始化:

1
var slice1 []int=[]int{1,2,3}

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

1
var slice2 []int=make([]int,3,10)

这表明定义一个容量为10的切片,其中存储了3个有效元素。

len()函数返回切片的有效数据个数,cap()函数返回切片的容量,append()函数向切片追加元素,copy()函数将一个切片中的数据拷贝到另一个中去。

切片可类比C++STL中的vector来使用。

  1. range关键字用来在for循环中遍历一个数组,切片,map,字符串等。它每次返回两个值,第一个是当前的索引,第二个是该索引对应的值。

  2. map

    Go语言中的map相当于一个语言层面的key-value的容器,底层使用哈希表来实现。可以如下创建一个key为int类型,value为string类型的map:

1
var a map[int]string

1
var a=make(map[int]string)

在map中添加元素:

1
a[10]="hello world"

删除元素:

1
delete(a,10)
  1. 接口

接口相当于C++中的抽象类。