Go后端学习- Go语言基础 | 青训营笔记

33 阅读5分钟

这是我参与「第五届青训营 」笔记创作活动的第1天

Go语言简介

Go语言是由Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,语法接近于C语言,但功能上更胜一筹。

Go语言优点

  1. 高性能、高并发

goroutine是Go语言并发设计的核心,是一种用户态轻量级的线程,Go语言内部也提供goroutine之间的内存共享,用Go语言内部的调度器GPM进行调度,成本比OS线程更低。

  1. 语法简单
  2. 丰富的标准库
  3. 完善的工具链

获取源码、编译、文档、测试、性能分析(pporf、go-torch)

  1. 静态链接
  2. 跨平台编译、编译速度快
  3. 垃圾回收

Go课程实战

MacOS下环境配置

通过Homebrew进行环境配置

brew install go

耐心等待一会儿,安装完成后通过go version测试

截屏2023-01-15 19.37.54.png

Go环境添加国内镜像

go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct

环境安装完成

截屏2023-01-15 19.54.11.png

基础语法

1. 变量

go语言变量一般通过var关键字声明,数据类型可以声明时写入,也可以交给go语言自动进行类型推断(常量const类型不确定只能推断)

var a = "initial"
// 变量a为String类型,值为initial
var b, c int = 1, 2
// 变量b和c为int类型,值为1和2
var d = true
// 变量d为bool类型,值为true
var e float64
// 变量e为float64类型,值为0
//go语言中未被初始化的变量会被赋予其类型的零值,如int类型的零值为0,string类型的零值为空字符串,bool类型的零值为false

2. 循环语句

go语言中for循环基本形式如下:
for init; condition; post { }
for condition { }
for  { }
循环流程与C语言类似
breakcontinue语句可以用于控制循环的执行,与C语言中的breakcontinue语句类似

3. 条件语句

3.1 if-else语句

if语句后面没有括号且后面需跟大括号,其余与C语言类似

3.2 switch语句

C语言中的switch语句,如果不加break,会继续执行下一个case,直到遇到break或者switch结束,而go语言是不需要加break的,go语言中switch功能更加强大。

在switch语句后不加任何值,相当于switch true,这种写法可以将if-else语句转换为switch语句,如第二个switch语句写法。

a := 2
switch a {
case 1:
	fmt.Println("one")
case 2:
	fmt.Println("two")
case 3:
	fmt.Println("three")
case 4, 5:
	fmt.Println("four or five")
default:
	fmt.Println("other")
}

t := time.Now()
switch {
case t.Hour() < 12:
	fmt.Println("It's before noon")
default:
	fmt.Println("It's after noon")
}

4. 数组

数组声明语法:var variable_name [SIZE] variable_type

数组初始化

b := [5]int{1, 2, 3, 4, 5}
fmt.Println(b)
//声明一个长度为5的int类型数组且内赋值1,2,3,4,5
//不长度可以把5换成...由go语言推断

go语言中数组长度不可改变

5. 切片

切片Slice是对数组的抽象,功能上类似于动态数组,与Python相似

//var slice1 []type = make([]type, len)
//通过make函数创建切片
s := make([]string, 3)
s[0] = "a"
s[1] = "b"
s[2] = "c"
fmt.Println("get:", s[2])   // c
fmt.Println("len:", len(s)) // 3
//可以通过append函数和copy函数增加切片容量
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println(s) // [a b c d e f]

c := make([]string, len(s))
copy(c, s)
fmt.Println(c) // [a b c d e f]
//切片支持通过slice[low:high]来获取子切片,其中包含low,不包含high,类似于python中的切片操作
fmt.Println(s[2:5]) // [c d e]
fmt.Println(s[:5])  // [a b c d e]
fmt.Println(s[2:])  // [c d e f]

6. map

go语言中存储kv键值对的map内部是无序的

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}
var m3 = map[string]int{"one": 1, "two": 2}
fmt.Println(m2, m3)

7. Range

range关键字用于循环中迭代数组、切片、map、字符串等,写法上range+对应迭代变量,返回索引-索引值或键值对。

8. 函数

go语言中函数支持多个返回值用,分割,一般都有一个返回结果,一个错误信息。

9. 结构体

9.1 定义结构体
type struct_variable_type struct {
   member definition
   member definition
   ...
   member definition
}

定义结构体后可以通过推断+结构体名+{k:v}定义结构体变量,k可以省略

9.2 定义结构体方法
func (Variable name struct_variable_type) function_name( [parameter list] ) [return_types] {
   函数体
}

10. 错误处理

因为go语言可以返回多个函数值,利用返回程序块状态值来反馈程序运行信息在go语言中是很好实现的。

11. 字符串操作

利用Strings库可以方便处理字符串

package main

import (
	"fmt"
	"strings"
)

func main() {
	a := "hello"
	fmt.Println(strings.Contains(a, "ll"))                // true
	//Contains判断字符串a中是否包含字符串ll,返回bool值
	fmt.Println(strings.Count(a, "l"))                    // 2
	//Count统计字符串a中字符串l出现的次数
	fmt.Println(strings.HasPrefix(a, "he"))               // true
	//HasPrefix判断字符串a是否以字符串he开头,返回bool值
	fmt.Println(strings.HasSuffix(a, "llo"))              // true
	//HasSuffix判断字符串a是否以字符串llo结尾,返回bool值
	fmt.Println(strings.Index(a, "ll"))                   // 2
	//Index返回字符串a中字符串ll第一次出现的位置,如果没有出现则返回-1
	fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
	//Join将字符串数组[]string{"he", "llo"}用-连接起来
	fmt.Println(strings.Repeat(a, 2))                     // hellohello
	//Repeat将字符串a重复2次
	fmt.Println(strings.Replace(a, "e", "E", -1))         // hEllo
	//Replace将字符串a中的e替换为E,-1表示替换所有的e
	fmt.Println(strings.Split("a-b-c", "-"))              // [a b c]
	//Split将字符串a按照-分割,返回字符串数组
	fmt.Println(strings.ToLower(a))                       // hello
	//ToLower将字符串a转换为小写
	fmt.Println(strings.ToUpper(a))                       // HELLO
	//ToUpper将字符串a转换为大写
	fmt.Println(len(a))                                   // 5
	//len函数计算字符串a的长度,返回5
	b := "你好"
	fmt.Println(len(b)) // 6
}

总结

在接触go语言之前主要写C和Python,通过青训营老师的讲解和自己一天的学习对go语言有了一个初步的认识,并通过课程案例和课后实践提高自己对go语言的熟练度。