这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
Go语言的好处
- 高性能,高并发;堪比c,cpp
- 语法简单,上手快;
- 标准库可靠丰富
- 工具链完备,编译,格式化,错误检查,文档,测试等
- go编译之后全是静态链接,编译结果就是可执行文件;不像cpp需要管理动态库
- 增量编译,速度极快
- 跨平台友好
- 垃圾回收
Go基础语法
基础语法视频课程和文档已经很细致了,这里就不重复劳动了。
课程老师的仓库github.com/wangkechun/… 里面有完整的go基本语法的完整案例。
有一点强调一下:结构体的成员函数,必须是指针的形式才能对结构体内部的字段进行修改,否则只能读到值。如图:
项目实战代码
猜数字
主要有以下几个要点
- rand库生成随机数,需要给定Seed。
- bufio的缓存流式处理。
- strconv做转换字符串。
在线词典
这个项目的思路是做一个cli应用,从翻译api来获取翻译结果并解析打印输出。
主要涉及,http请求,json的序列化/反序列化,对应分别是net/http,encoding/json库。
其中提供了利用浏览器和网页工具快速生成请求代码的方法。
生成复杂请求:
- 通过浏览器开发者工具找到api的请求。
- 右键转化为cURL,拿到的curl访问的命令。
- curlconverter.com/go/ 这个网站提供了命令转成对应语言代码的功能。
生成复杂的解析response的代码:
- oktools.net/json2go 这个网站可以实现json转go代码。
其中两点需要强调:
- defer的用法,defer执行的时候是该语句当时的变量状态;defer一般直接跟在资源获取成功的后面写对资源进行释放的语句。
- log.Fatal(),这个函数老师没用讲,这个函数相当于执行
os.Exit(1),打印完日志之后之后会直接结束程序。即defer什么的后面的通通不会再执行了。
proxy
这个项目是实现一个sock5代理。sock4代理的本质是将请求转发代理服务器,用户和目标服务器不直接通信,而是先和代理服务器认证建立连接,然后由代理服务器代劳和目标服务器进行通信。
本项目实现的是一个sock5的服务端程序,程序会开一个for循环不断监听作为服务。当有client访问代理服务器时,服务端处理该请求,先对客户端进行auth,解析其字段并验证有效性;然后进行连接,先解析获取到要访问的目标服务器的信息,然后通过net.Dial与目标服务器建立连接,建立成功后,通过原连接conn通知客户端sock5字段信息。
建立连接之后,要实现双向通信,需要代理服务端这里进行信息的转发。这里建立两个协程,通过io.Copy进行流缓存区的双向拷贝。
这里存在一个问题:如果不做处理,代码会直接运行到结束,connect协程会直接结束,这是违反逻辑的。我们需要在一方的行为发送异常后,认为连接中断。这里使用context的cancel机制来进行处理。
当两个协程中的一个停止之后,会执行cancel()函数关闭context。
// Done returns a channel that's closed when work done on behalf of this
// context should be canceled.
Done() <-chan struct{}
// func Stream(ctx context.Context, out chan<- Value) error {
// for {
// v, err := DoSomething(ctx)
// if err != nil {
// return err
// }
// select {
// case <-ctx.Done():
// return ctx.Err()
// case out <- v:
// }
// }
// }
看下官方给的这个示例:可以通过类似机制来控制stream的关闭。
本文同步知乎