这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
Go语言基础
Go语言的特性与优势
- 高性能、高并发(原生支持go routine)
- 语法简单,易于学习(类似于C语言,但简化了很多特性)
- 标准库丰富(标准库自带http包,网络包等常用库)
- 工具链完善(编译、格式化、包管理、代码提示、测试框架等都是自带的)
- 采用静态链接(发布可执行文件时不用面对库的兼容性问题)
- 编译速度快(比C++快很多)
- 跨平台(Win/Linux/Mac,交叉编译)
- 支持垃圾回收
入门
开发环境配置
-
安装Go语言
pacman -S go -
配置集成开发环境
- VS Code,需要配置插件
- Jetbrains的Goland
基础语法
Hello World程序
package main
import "fmt"
func main(){
fmt.Println("Hello World")
}
一些说明:
- package main: 包的名字
- import "fmt" 导入fmt包
- func main() 定义主函数
- fmt.Println 一个包里面,大写字母开头的符号是导出的
变量
使用var关键字来定义变量
var a = "initial"
var b, c int = 1, 2
var d = true
var e float64
f := float32(e)
g := a + "foo"
- 常见的变量类型分类:整数、浮点、字符串、布尔值
- 变量的类型写在变量名后面,有初值的情况下可以自动推导类型
- 可以使用 := 快速定义一个变量(不能用于全局变量)
- 使用const代替var来定义常量
if控制流
if 7 % 2 == 0{
fmt.Println("7 is even")
}else{
fmt.Println("7 is odd")
}
- 不使用括号
循环控制流
Go语言的循环只有for一个关键字,并且同if一样不使用括号
但是可以有多种形式
for{
//statement
}// 死循环
for i:=1; i<0;i++{ //可以省略任意分句
//statement
}
for x >=0 {
//statment
}
break和continue的使用与C/C++类似
switch case控制流
与C/C++的区别:
- 不需要额外的break语句,如果想像C/C++一样,使用fallthrough
- 条件不需要是整数类型,可以是任意类型,即可以完全替代else if语句
数组与切片
定义数组:
var a [5]int
a的类型是[5]int,长度是类型的一部分
创建切片:
b := make([]int, 5)
需要注意append时,需要使用append的返回值
map
使用make创建一个map
m := make(map[string]int)
使用delete删除kv对
delete(m, "key")
返回值的获取:val, ok := m["key"]
遍历map:for k,v := range m {...}
函数
func add(a int, b int) (int, int){
return a+b, a-b
}
同变量声明一样,返回值类型写在函数声明最后面
此外,Go语言原生支持多返回值(多见于if err!=nil的前面)
指针
可以认为Go中的指针是C/C++中指针的简化版
不支持指针的加减操作,即无法通过*(ptr+i)这样的形式遍历数组了
结构体
定义结构体
type user struct{
name string
age int
}
定义成员函数
func (u *user) grow() int{
u.age ++
return u.age
}
_ = u.grow()
错误处理
通常使用多返回值配合err的形式,例如
v, err := findUser(u)
if err!= nil{
// handle error
}
字符串处理
导入strings包,然后使用如strings.Contains(s, substr)这样的字符串处理函数。
另外,获取字符串长度可以使用内置函数len(s)
导入fmt包可以对字符串进行格式化处理,相比于C,新增了一个%v的类型描述符,可以自动匹配传入参数类型。
处理json
使用标准库的encoding/json包
具体而言,使用json.Marshal(b)和json.Unmarshal(buf, &b)两个函数来序列化/反序列化json对象
需要保证struct的成员是导出的,此外可以使用json: tag来自定义字段标签。
时间处理
使用time包
使用time.Now()获取当前时间
使用2006-01-02 15:04:05来格式化时间字符串
数字与字符串的转换
使用strconv包
使用strconv.ParseInt和strconv.ParseFloat来从字符串中解析数值数据,使用strconv.Atoi来将数值数据转换成对应的字符串。
进程参数,环境变量获取
使用os包
使用os.Args来获取启动时的进程参数
使用os.Getenv("ENVNAME")来获取环境变量,类似的,使用os.Setenv("AA","BB")来设置环境变量
三个例子
猜数字游戏
使用到前面未介绍的库函数:
-
math/rand
通过
rand.Seed(time.Now().UnixNano())来初始化随机数种子 -
bufio
创建读取流:
reader := bufio.NewReader(os.Stdin)
命令行词典
如何获取API
- 使用开发者工具,Copy As cURL
- 在curlconverter.com/#go) 中粘贴并得到Go语言的http请求代码
- 复制到项目中,进行修改
代码生成工具
-
将Json对象转换为Go中的struct
Socks5代理
-
使用cURL来测试:
curl --socks5 127.0.0.1:1080 -v http://g.cn -
使用net包
server, err := net.Listen("tcp", "127.0.0.1:1080") if(err!=nil){ panic(err) } for{ client, err:= server.Accept() ... }
-
Socks5协议
-
客户端 <--> Socks5服务器 <--> 目标服务器