Go语言学习
基础语法
变量与常量
变量
go是强类型语言,就是说在变量使用之前需要先声明。
变量的声明的语法如下:
① var 变量名 变量类型 [= 初始值]
② 变量名 := 值
注: 括号部分在声明时可以省略,没有赋初值默认值为0
支持一次声明单个变量:
var a int = 10
也支持一次声明多个变量:
var a,b,c int = 10,20,30
注:若声明时直接赋值,则可以省略类型,能直接进行类型推断
常量
常量的声明与变量类似,只需要把var关键字换成const即可
const test = 20
test = 30 // 会报错,常量不可变
条件分支语法
if-else if -else类型
与C / C++ / Java类似,不同的是go在if后面的条件不需要加括号,并且在条件后面必须加大括号{}
语法如下:
if 条件1{
// 内容
}else if 条件2.{
// 内容
}else{
// 内容
}
var a = 10
if a < 10 {
fmt.Println("0<a<10")
} else {
fmt.Println("a>=10")
}
switch类型
switch expression{
case value1: // 如果 expression 等于 value1,则执行这里的代码块
case value2: // 如果 expression 等于 value2,则执行这里的代码块
... default: // 如果 expression 不等于任何一个 value,则执行这里的代码块
}
var i = 1
switch i {
case 0:
fmt.Println("i is zero")
case 1:
fmt.Println("i is one")
case 2:
fmt.Println("i is two or greater")
default:
fmt.Println("i is not zero, one, two")
}
注:可以在每个case代码块末尾使用fallthrough语句强制执行下一个case代码块
switch i {
case 0:
fmt.Println("i is zero")
case 1:
fmt.Println("i is one")
fallthrough
case 2:
fmt.Println("i is two or greater")
default:
fmt.Println("i is not zero, one, two")
}
注:在Go语言中,switch语句默认情况下是自带break的,即执行完一个case后会自动退出switch语句。如果需要连续执行多个case,可以使用fallthrough语句。同时,switch语句也可以不带表达式,用作if-else-if-else的替代语句
switch {
case a < b:
fmt.Println("a is less than b")
case a > b:
fmt.Println("a is greater than b")
default:
fmt.Println("a and b are equal")
}
循环结构
在go中有for循环,range循环、无限循环三种形式,没有while和do-while循环
语法如下:
for循环
for 初始值;循环条件; 执行完循环后的变化 {
// 循环体
}
for i := 0; i < 10; i++ {
fmt.Println(i)
}
range 循环
range 循环用于遍历数组、切片、映射等集合类型。range 循环的基本语法如下:
for index, value := range 条件{
// 循环体
}
for index, value := range []int{1, 2, 3} {
fmt.Println(index, value)
}
无限循环
无限循环是指在每次迭代中重复执行一段代码,没有循环条件,直到程序显式地请求退出。无限循环的基本语法如下:
for {
// 循环体
}
直到程序显式地调用 break 或 os.Exit 函数退出循环
for {
fmt.Println("Hello, world!")
}
数组
在go语言中,数组是一种固定长度的数据结构,由相同类型的元素组成。可以通过下标索引的方式访问。
数组在声明时需要指定长度。声明数组的语法如下:
var 数组变量名[ 数组长度 ] 元素类型
也可以使用数组字面量语法创建和初始化数组, 如下:
var 数组变量名= [数组长度] 元素类型{value1, value2, ..., valueN}
var a [3]int // 声明一个长度为 3 的 int 类型数组
a[0], a[1], a[2] = 1, 2, 3 // 初始化数组元素
var b = [3] int{4,5,6} // 声明一个长度为 3 的 int 类型数组并初始化
b := [3]int{4, 5, 6} // 等价
c := [...]int{7, 8, 9} // 省略长度的数组声明,根据初始值自动推导数组长度
d := [3][3]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}} // 声明一个二维数组
切片
Go 语言中的切片是一个引用类型,表示一个动态数组,可以根据数据的实际情况动态伸缩。切片的底层是一个数组,切片的长度可以动态改变,但容量不能超过这个底层数组的长度。切片使用的语法如下:
变量名:= make([]类型, length) // 声明一个指定长度的切片
或者
变量名:= make([]类型, length,capacity) // 声明一个指定长度、容量的切片
当没有指明容量时,表明容量和长度相等
可以理解为:长度是切片当前的元素个数,容量是切片可容纳的最大元素个数
var s1 []int // 声明一个初始值为 nil 的 int 类型切片
s2 := make([]string, 5) // 声明一个长度为 5 的 string 类型切片
s3 := make([]float64, 5, 10) // 声明一个长度为 5,容量为 10,float64 类型切片
s4 := []int{1, 2, 3} // 使用切片字面量创建切片
s4 = append(s4, 4, 5, 6) // 向切片尾部追加三个元素
当长度!=容量时,可以使用append来追加切片的元素,但需要用变量接收返回值
Map
和java中的map类似,存放的形式是key-value,声明语法如下:
变量名:=make(map[key类型] value类型)
m := make(map[string]int)
m["111"] = 1
m["222"] = 2
m["333"] = 3
fmt.Println(m)
可以通过下列方式查看是否存在对应的key和value
r, ok := m["111"]
fmt.Println(r, ok)
前面是value,后面是是否存在
也可以通过delete来删除一个k-v对
m := make(map[string]int)
m["111"] = 1
m["222"] = 2
m["333"] = 3
fmt.Println(m)
delete(m, "111")
r, ok := m["111"]
fmt.Println(r, ok)
函数
在go语言中,函数的返回值支持多个返回,通常情况下返回的第一个值是真正的返回值,第二个值返回的是布尔类型的错误信息,函数的定义如下:
func 函数名 (参数名 参数类型,......) (返回值1 返回值类型,......) {
// 函数体
}
函数的参数列表和返回值列表都是可选的,但是函数名、函数体和左右花括号都是必须的
func add(a int, b int) (v int, ok bool) {
if (a + b) > 0 {
ok = true
} else {
ok = false
}
return a + b, ok
}
v, ok := add(2, 3)
fmt.Println(v, ok)
指针
这里和C语言的指针用法类似。
结构体
这里也和C语言的结构体类似,仅贴出课程中的例子理解一下即可
这里需要注意一下结构体方法的使用:
类似类的成员方法
错误处理
go语言对错误的处理不像java那样用异常类去处理,go只需要在函数返回的时候使用一个error来作为返回值,返回时使用 errors.New("错误信息")的方式创建一个错误返回,在调用函数时使用一个变量来接收error的值,如果error不为nil,则表示有错误,示例如下:
func add(a int, b int) (v int, err error) {
if (a + b) > 0 {
return a + b, nil
} else {
return 0, errors.New("相加的和小于0")
}
}
v, err := add(2, 3)
if err == nil {
fmt.Println(v)
} else {
fmt.Println(err)
}
结果
v, err := add(2, -3)
if err == nil {
fmt.Println(v)
} else {
fmt.Println(err)
}
字符串操作
json格式序列化
首先需要创建一个结构体,并且字段的首字母用大写:
type user struct{
Name string
Age int
}
然后通过调用json.Marshal(结构体变量) ,就可以把一个结构体变量序列化成一个json格式的字符串了
u := user{Name: "xiaoming", Age: 18}
json, err := json2.Marshal(u)
if err == nil {
fmt.Println(string(json))
} else {
fmt.Println(err)
}
同时可以用json.Unmarshal(json,结构体变量)将json反序列化成结构体类型