Go语言基础课程笔记| 青训营笔记

131 阅读3分钟
这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记

本文主要介绍Go语言基础语法,含部分C++类比解释

GoLand使用

学习Go语言推荐使用GoLand,Jetbrains官网能申请学生免费

文件->新建->Go 文件 - 编辑配置 - Go 构建 运行种类选目录

或者在终端输入 go run main.go运行go文件

记得package包名设置为main

GoLang基础语法

1 变量声明

var [name1, name2] [type] = [value1, value2] 

其中name1, name2为声明的变量名,type为变量的类型名称,value1, value2为对应的值

部分常见类型如下:

int float32 float64 string ...

2 循环

无限循环格式如下:

for {
    ...
}   //相当于while (1) {...}

一般循环格式如下:

for i := 0; i < n; ++i {
    ...
} 

OR

for i < n {
    .... 
    
    i = i + 1
} 

注意使用下面这种循环方式时变量i需要提前声明

3 IF-ELSE

if的同时可以声明一个局部变量,作用范围只在该if-else语句内

if ([init var]; check) {
    ...
} else if (check) {
    ...
} else {
    ...
}

当然也可以不额外声明变量

4 SWITCH

格式如下:

switch x {
case 1:
    ...
case 2:
    ...
case 3, 4:
    ...
default:
    ...
}

5 Array

即数组,长度固定

声明格式如下:

var a [size]type
b := [size]type{init list}
var twoD [size1][size2]int

size为数组大小(长度) 举例:

var a [5]int{1, 2, 3, 4, 5}
var twoD [2][3]int{{0, 1, 2}, {1, 2, 3}}
fmt.Println(a)
fmt.Println(twoD)

结果如下:

//1d:  [1 2 3 4 5]
//2d:  [[0 1 2] [1 2 3]]

以上也体现了Go语言中输出数组的格式,可以直接Println输出

6 slice (可变长Array)

s := make([]value type, [length])
s := []string{"a", "b", "c"} // ["a" "b" "c"]

与array相比 声明不指定长度

与slice有关的部分函数:

len(s) //类比C++中的s.length()
​
s.append(s, "x1", "x2") //类比C++中的s.push_back()copy(a, b) //将b赋值给a

7 map

声明方式如下:

m := make(map[key type]value type)
m := map[key type]value type{"key":val, ...}
var m = map[key type]value type{"key":val, ...}

key type为key的类型名 value type为value的类型名

map的部分常用函数如下:

len(m)
a, b := m["key"]

返回值可类比C++中的 pair<value, bool(has key)>,其中bool值表示是否存在key为“key”的键值对

map的默认输出:

fmt.Println(m) // map[key1:val1, key2:val2...]
delete(m, "key")

删除key为“key”的键值对

8 range (for each)

for each循环 可类比C++中的

for (auto [a, b] : array) {
    ...
}

格式如下:

for a, b := range array {
    //a = index, b = value
}
for a := range array {
    //a = index
}
for a, b := range map {
    //a = key, b = value
}
for a := range map {
    //a = key
}

9 function

func function_name(valname type, ...) return_type {
    return...
}
func function_name(valname1, valname2 type1, ...) return_type {
    return...
}
func function_name(valname type) (return_type1, return type2) {
    return val1, val2
}

以第一个举例,func为关键字,function_name函数名,valname为传入的参数名称,type为对应的参数类型 return_type为函数返回的值的类型

若没有返回值可不填,如第三个例子所示

10 pointer

example:
func f1(a int*) {
    *a += 1
}
func f2() {
    a := 0
    func1(&a)
}

配合结构体使用,函数传参可节省拷贝开销

11 struct

type struct_name struct {
    val1 type1
    val2 type2
    ...
}
​
显式定义://可部分定义
a := type{type1: val1, type2: val2}
可隐式定义:
a := type{val1, val2}

上文讲到使用struct指针能节省拷贝开销

另外如果要对结构体本身进行修改 下面的函数无法实现

func (val1 struct_type) func_name(...) return_type {
    return ...
}

下面的指针结构体函数可修改结构体本身

func (*val1 struct_type) func_name(...) {
    return ...
}

12 error

使用前需要导入errors包:

import "errors"

函数可返回error类型,表示可能发生错误:

return errors.New("...")

否则

return nil

“...”代表错误信息,string类型

13 string

使用前需要导入包string

import "string"

声明方式:

s string

常用成员函数 以下函数用法为strings.func_name()

Contains(s, "substring")      //bool, 是否包含子串
Count(s, "substring")         //int 子串计数
HasPrefix/Suffix              //bool 是否包含前/后缀
Index(s, "substring")         //int 子串出现的位置
Join([]string{"a", "b"}, "-") //string("a-b") 用指定符号连接string集合
Repeat(s, 3) string(s + s + s)//string 末尾自我复制
Split("a-b-c", "-")           //array-string [a, b, c] 字符串按指定字符分离
ToLower/ToUpper               //同一转为小/大写
len(s)                        //int 字符串长度

注意含中文字符的string 的 len 可能不符预期,因为中文的编码方式与英文字母不同

14 json

使用前需要导入json包:

import "encoding/json"

常用函数:

buf := json.Marshal(struct_item)//每个字段为大写开头
//return array, err

string(json.Marshal(struct_item)) = struct_item
json.MarshalIndent(val1, every, has)
//每一行添加(string)"every", 行非空添加(string)"has"

err := json.Unmarshal(buf, &val2)//val2 = val1

注意一般json出来的风格为为一个字段首字母大写,若需要自定义,在字段后添加如下:

type info struct {
    Age int `json:"age"`
}

15 time

使用前需要导入time包:

import "time"

常用函数:

time.Now() //return string
diff := t.Sub(t2) //两事件差值(string) XhYmZs
diff.Minutes(), diff.Seconds()
t.Format("2006-01-02 15:04:05")//格式化所用日期固定
time.Date(Y, M, D, H, M, S, 0, [时区](time.UTC))
time.Parse("2006-01-02 15:04:05", "...")//return string

字符串与数字的转换 使用前需要导入strconv包:

import "strconv"

常用函数:

strconv.ParseFloat(string, [精度]64)
strconv.ParseFloat(string, [进制],[精度]64)//认为string为[进制]的数字,转为10进制
strconv.Atoi("123") //return int = 123

以上函数都会返回类似C++中的pair<x, error>类型