Go语言基础语法|青训营笔记(一)
这是我参与「第五届青训营 」笔记创作活动的第1天
1.Go语言结构
package main
import (
"fmt"
)
func main() {
fmt.Println("hello world")
}
package:Go语言的代码通过包(package)组织,包类似于其它语言里的库(libraries)或者模块(modules)。一个包由位于单个目录下的一个或多个.go源代码文件组成,目录定义包的作用。每个源文件都以一条package声明语句开始,这个例子里就是package main,表示该文件属于main包。
import:表示该程序需要的包,本例中使用了fmt包,包含了标准格式化IO(输入输出)的函数。
func main():是程序开始执行的函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数(如果有init()函数则会先执行该函数)。
2.Go语言数据类型
go语言数据类型主要包括布尔类型、数字类型、字符串类型以及一些派生类型,如指针类型、数组类型、结构化类型、Map类等。
go语言声明变量与其他语言声明不太一样,go语言使用var关键字声明变量,变量声明时可以不给定数据类型,编译器根据初值判断对应得到数据类型。也可以不初始化,无初始化则默认零值。
var identifier type
var identifier1, identifier2 type //一次声明多次变量
go语言也可以使用:=声明变量,如果变量已经使用 var 声明过了,再使用:=声明变量,就产生编译错误。需要注意的时,:=只能在函数体内使用,不能用于声明全局变量
v_name := value
常量使用const关键字声明,常量是一个简单值的标识符,在程序运行时,不会被修改的量。常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。其定义格式如下:
const identifier [type] = value
同样的,常量的定义也可以省略数据类型,由编译器判断数据类型。
3.循环语句
与其他语言不通,Go语言中只有for循环,其格式与C语言类似,但省略了for后面的括号。
for init; condition; post {
...
}
- init: 一般为赋值表达式,给控制变量赋初值;
- condition: 关系表达式或逻辑表达式,循环控制条件;
- post: 一般为赋值表达式,给控制变量增量或减量。
4.条件语句
Go 语言提供了以下几种条件判断语句:
| if 语句 | if 语句由一个布尔表达式后紧跟一个或多个语句组成。 |
|---|---|
| if...else 语句 | if 语句 后可以使用可选的 else 语句, else 语句中的表达式在布尔表达式为 false 时执行。 |
| if 嵌套语句 | 你可以在 if 或 else if 语句中嵌入一个或多个 if 或 else if 语句。 |
| switch 语句 | switch 语句用于基于不同条件执行不同动作。switch自带break,即执行完一个case自动跳出语句,不会执行剩下的case语句。 |
5.数组与切片
数组是具有相同唯一类型的一组已编号且长度固定的数据项序列,这种类型可以是任意的原始类型例如整型、字符串或者自定义类型。数组元素可以通过索引(位置)来读取(或者修改)。其定义格式如下,需要指定数组的元素类型和元素个数。
var variable_name [SIZE] variable_type
可以通过索引来访问数组中的元素,索引数必须小于数组中元素的个数。
数组的长度不可改变,在特定场景中这样的集合就不太适用,Go语言提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。切片的声明格式如下:
var slice1 []type = make([]type, len)
也可以简写为
slice1 := make([]type, len)
切片与数组相比其长度是不固定的,在声明过后仍可以追加元素,追加元素使得切片容量增大。
6.Map
Map 是一种无序的键值对的集合。Map 最重要的一点是通过 key 来快速检索数据,key 类似于索引,指向数据的值。Map 是一种集合,所以我们可以像迭代数组和切片那样迭代它。Map的声明格式如下:
map_variable := make(map[key_data_type]value_data_type)
下面实例演示了创建Map和对map的删除等操作
func main() {
m := make(map[string]int)
m["one"] = 1
m["two"] = 2
fmt.Println(m) // map[one:1 two:2]
fmt.Println(len(m)) // 2
fmt.Println(m["one"]) // 1
fmt.Println(m["unknow"]) // 0
r, ok := m["unknow"]
fmt.Println(r, ok) // 0 false
delete(m, "one")
m2 := map[string]int{"one": 1, "two": 2, "three": 3, "five": 5, "six": 6, "ten": 11}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3) //map的遍历是完全无序的
}
其中注意到m2的输出与一开始赋初值时的顺序不一样,go语言中Map的遍历是完全随机无序的。
7.函数
go语言中函数的定义格式如下:
func function_name( [parameter list] ) [return_types] {
函数体
}
- func:函数由 func 开始声明
- function_name:函数名称,参数列表和返回值类型构成了函数。
- parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选的,也就是说函数也可以不包含参数。
- return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
- 函数体:函数定义的代码集合。
8.指针
Go 语言中指针是很比较简单的,Go 语言的取地址符是&,放到一个变量前使用就会返回相应变量的内存地址。
一个指针变量指向了一个值的内存地址。 类似于变量和常量,在使用指针前你需要声明指针。指针声明格式如下:
var var_name *var-type
var-type 为指针类型,var_name 为指针变量名,*号用于指定变量是作为一个指针。
9.结构体
Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。结构体定义需要使用 type 和 struct 语句。struct 语句定义一个新的数据类型,结构体中有一个或多个成员。type 语句设定了结构体的名称。结构体的格式如下:
type struct_variable_type struct {
member definition
member definition
...
member definition
}
定义了结构体后,就可以用于变量的声明,声明结构体变量的格式如下:
variable_name := structure_variable_type {value1, value2...valuen}
或
variable_name := structure_variable_type { key1: value1, key2: value2..., keyn: valuen}
如果要访问结构体成员,需要使用点号.操作符,格式为:结构体.成员名
Go语言中还可以为结构体定义方法,类似与其他语言的类成员函数。其定义格式为:
func (struct_name,struct_type) function_name( [parameter list] ) [return_types] {
函数体
}
定义之后可以直接使用.来调用结构体方法。
10.错误处理
Go语言中的error包可以很简单进行错误处理,如下示例所示:
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, errors.New("not found")
}
要判断函数的返回值是否存在错误,可以在返回值里多加入一个参数用于接受错误信息。当函数正常运行时返回所需要的参数值,错误指示参数返回零值;而出现错误时则返回错误信息。
11.总结
以上只是Go语言的一些最基础的语法知识,Go语言还有其他更进阶高级的用法,仍需要认真学习。加油!!