这是我参与「第五届青训营 」笔记创作活动的第1天
Go语言简介
Go语言是由Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,语法接近于C语言,但功能上更胜一筹。
Go语言优点
- 高性能、高并发
goroutine是Go语言并发设计的核心,是一种用户态轻量级的线程,Go语言内部也提供goroutine之间的内存共享,用Go语言内部的调度器GPM进行调度,成本比OS线程更低。
- 语法简单
- 丰富的标准库
- 完善的工具链
获取源码、编译、文档、测试、性能分析(pporf、go-torch)
- 静态链接
- 跨平台编译、编译速度快
- 垃圾回收
Go课程实战
MacOS下环境配置
通过Homebrew进行环境配置
brew install go
耐心等待一会儿,安装完成后通过go version测试
Go环境添加国内镜像
go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
环境安装完成
基础语法
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语言类似
break和continue语句可以用于控制循环的执行,与C语言中的break和continue语句类似
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语言的熟练度。