Go语言基础语法 | 青训营笔记

88 阅读3分钟

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反序列化成结构体类型