(一)Go基本语法
变量
变量声明
显式声明
如果我们未为一个变量初始化,则必须显式指定变量类型
如果声明时不指定具体的值,则会被赋值为默认值。
1 | var str string // str的值为""(空字符串) |
快速声明赋值
Go 支持变量类型自动推断,也就是说,当我们立即为一个变量进行初始化时,其类型是可以省略的
可以通过
:=
符号以一种简单的方式(也是实际上最常用的方式)声明一个变量
1 | a, b := 1, 2// Go 支持多个变量在同一行同时声明 |
常量声明
可以使用 const
关键字代替 var
关键字来创建一个常量(不可变变量)
1 | const str string = "我是字符串" |
流程控制
if
Go
的if
语句和C、Java
类似,只不过if
后面没有括号,但是加上括号也能正确运行if
后面的开始大括号必须跟if在同一行,不能换行(会报错)。
1 | num1, num2 := 1, 2 |
if
语句后面也可以定义变量,但只能用一个分号。也支持if-else-if
语句。
1 | if num1, num2 := 1, 2; num1 < num2 { |
for
在Go
里没有while
和do-while
循环,只有for
循环。Go
的for
循环包含了for
和while
的功能。
用for
定义死循环,相当于while(true)
。
1 | for { |
switch
switch
语句也和C、Java
的``switch语句类似,只不过
switch后面不需要加括号,
case里也不需要加
break,
Go的
switch 默认情况下
case最后自带
break语句,匹配成功后就不会执行其他
case,如果我们需要执行后面的
case,可以使用
fallthrough` 。
1 | num := 2 |
Go
的switch
可以匹配任意类型,也可以实现if-else
的功能,在switch
后面不加匹配条件,可以在case
里进行匹配。
1 | t := time.Now() |
数组
一维数组
1 | // 声明一个长度为5的数组 |
多维数组
1 | var twoD [2][3]int |
切片
声明
有点像
Java
的List
切片声明需要通过
make
来进行,需要指定切片的类型以及长度
1 | // 声明一个空切片,长度为3,容量为10 |
操作
对切片元素的操作,可以像数组一样操作:
1 | s := make([]string, 3) |
添加
可以通过append
方法向切片中添加元素,因为切片会涉及到扩容,所以需要一个变量来接收返回值
1 | s = append(s, "d") |
复制
可以通过copy
方法对切片进行复制,复制后是两个独立的切片,更改元素值相互不影响。
1 | go复制代码c := make([]string, len(s)) |
切片
相当于Java
中的substring
1 | go复制代码// 返回下标2到4的值 |
Map
无序
声明
声明一个key
为string
,value
为int
的空Map
1 | m := make(map[string]int) |
声明的同时对其进行初始化操作:
1 | m2 := map[string]int{"one": 1, "two": 2} |
访问和操作
1 | m["one"] = 1 |
Go
在查询key
时返回了两个值,一个是value
,另一个是bool
类型的值代表是否存在
1 | r, ok := m["unknow"] |
可以使用delete
函数来删除Map
中的键值对
Goland
中可以通过map.delete
快速生成
1 | delete(m, "one") |
range
有点像JavaScript
的解构赋值
数组、切片、Map
都可以使用range
来遍历,通过range
可以得到索引和对应的值
1 | nums := []int{2, 3, 4} |
函数
Go
函数不同于Java
,返回值写在最后面,而且可以同时返回多个值
一般来说,第一个是函数的返回值,第二个是错误信息
1 | func exists(m map[string]string, k string) (v string, ok bool) { |
指针
Go
支持指针,相对于C语言
,Go
的指针功能十分简单,当然功能也很有限,主要用途就是对函数传入的参数进行修改。
默认情况下,Go
函数的参数传参是值传递,也就是拷贝了一个副本,对其修改不会影响原来的值,如果要对原来的值也要变的话,需要使用指针。
1 | func add2(n int) { |
结构体
结构体变量
和C
语法差不多,相当于Java
的对象
1 | type user struct { |
结构体的初始化,可以指定字段初始化,也可以全部初始化。
1 | a := user{name: "wang", password: "1024"} |
对于结构体内部成员的访问可以通过.
操作符来进行访问或赋值。
1 | var d user |
结构体方法
相当于Java
类的成员函数
在一个普通方法的func
关键字后面加上对应结构体信息,就代表这个方法是属于结构体的。
为user
结构体添加一个检查密码的函数:
1 | func (u user) checkPassword(password string) bool { |
为user
结构体添加一个重置密码的函数,因为要修改结构体内部的值,所以要使用指针类型:
1 | func (u *user) resetPassword(password string) { |
结构体方法的调用:
1 | a := user{name: "wang", password: "1024"} |
错误处理
Go
内置的错误接口提供了非常简单的错误处理机制,error
类型是一个接口类型,其定义如下:
1 | type error interface { |
Go
函数可以返回多个值,通常函数的最后一个值用来代表错误信息,在函数内部可以使用errors.New
可返回一个错误信息:
1 | func findUser(users []user, name string) (v *user, err error) { |
如果函数不出现错误的话,可以直接返回nil
。
在调用函数的时候,需要用多个变量来接收函数的返回值,我们可以通过函数的返回值来判断是否发生了异常。
1 | u, err := findUser([]user{{"wang", "1024"}}, "wang") |
标准库
Go
内置了非常丰富的标准库工具,包括字符串操作、字符串格式化、json
处理、时间处理等
字符串操作
1 | a := "hello" |
字符串格式化
Println
最为常用作用为打印并换行,Printf
可以按指定格式打印字符串。
+v
可以打印字段和值详细信息。
#v
可以打印出整个结构体的构造以及详细信息。
1 | go复制代码s := "hello" |
json处理
Go
在处理json时十分简单,只需要将结构体中的字段第一个字母变成大写就能用内置的JSON
工具进行处理。
Go
中一些特殊的类型,比如Channel
、complex
、function
是不能被解析成JSON
的。
Go
中JSON
对象只支持string
作为key
,对于map
,那么必须是map[string]T
这种类型,T
可以是Go
语言中任意的类型。
Go
的json
处理是通过Marshal
、Unmarshal
方法来进行处理的。
Marshal
用于自定义编码json
的方法,也就是将变量、对象转成json
,转换之后需要用string
方法强转一下,否则会打印出的是16进制字符串。
Unmarshal
用于自定义解码json
方法,也就是将json
转为对象。
1 | type userInfo struct { |
时间处理
Go
提供了很多常用的时间处理函数,例如Now、解析字符串、转字符串、获取时间戳等。在操作时间相关的方法时,需要导入time
包。
1 | // 获取当前时间 |