这是我参与「第五届青训营 」伴学笔记创作活动的第 1 天
课堂重点
今天学习了两节课,分别是:
- Go语言的基础
- Go语言的实战案例
基础包含:
- Go开发环境的配置,先下载Golang语言,后续再配置Go语言开发环境选择使用VS Code或者 Goland
- 基础语法
- 标准库函数
- go开启协程的方式,以及管道channel的介绍(后续查阅资料进一步学习的)
- 三个实战项目(猜数字、命令行字典、socket5代理服务器)
详细介绍
- 对于Go语言开发环境,我选择是的VS Code,之前就已经下载了,只需要安装插件即可,外存占用低,也不需要Goland的注册许可证
- 对于基础语法中map和slice切片是最为常用也最为重要的数据类型。
对于map 我们跟我们可以用 make 来创建一个空 map ,这里会需要两个类型,第一个是那个 key 的类型, 另一个是 value 的类型。有其他语言基础会更好理解 我们可以从里面去存储者取出键值对。可以用 delete 从里面删除键值对。golang的map是完全无序的,遍历的时候不会按照字母顺序,也不会按照插入顺序输出,而是随机顺序。
对于切片,因为 slice 的原理实际上是它有一个它存储了一个长度和一个容量,加一个指向一个数组的指针,在你执行 append 操作的时候,如果容量不够的话,会扩容并且返回新的 slice ,因此在函数之间传递切片的时候,都是引用传递。不用担心会产生局部变量无法操作原切片 3.标准库函数有两个最常用的包分别为:
strings包中的操作字符串的函数
a :="hello" fmt.PrintIn(strings.Contains(a,"ll")) // true
fmt.Println(strings.Count(a,"l")) // 2
fmt.Println(strings.HasPrefix(a,"he")) // true
fmt.Println(strings.HasSuffix(a,"llo")) // true
fmt.Println(strings.Index(a,"ll")) //2
fmt.Println(strings.Join([]string["he","llo"},"-")) // he-llo
fmt.Println(strings.Repeat(a, 2)) // hellohello1
fmt.Println(strings.Replace(a,"e","E"-1)) // hEllo
fmt.Println(strings.Split("a-b-c",*-")) //[a b c]
fmt.Println(strings.ToLower(a)) //hello
fmt.Println(strings.ToUpper(a)) //HELLO
fmt.Println(len(a)) //5
fmt字符串格式的方法
s :="hello"
n := 123
p := point(1,2)
fmt.Println(s,n) // hello 123
fmt,Println(p) //{1 2}
fmt.Printf("s=%v\n",s) // s=hello
fmt.Printf("n=%v\n",n) // n=123
fmt.Printf("p=%v\n",p) //p = {1 2}
fmt.Printf("p=%+v\n",p) // p={x:1 y:2}
fmt.Printf("p=%#v\n",p) // p=main.point{x:1,y:2)
f := 3.141592653
fmt.Println(f) //3.141592653
fmt.Printf( "%.2f\n",f) //3.14
实践练习
猜数字游戏,只是熟悉Go语法。值得注意的是使用的随机数
import (
"math/rand"
"time"
)
rand.Seed(time.Now().UnixNano())
secretNumber := rand.Intn(maxNum)
以及使用reader来获取屏幕的输入
import (
"bufio"
"os"
"strconv"
"strings"
)
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
fmt.Println("错误")
return
}
input = strings.TrimSuffix(input, "\n")
input = strings.TrimSuffix(input, "\r")//对于不同电脑可能会出现的转义字符,需要去掉
guess, err := strconv.Atoi(input)
命令行字典,更多是的json、抓包和第三方工具的使用
通过获取浏览器的返回的数据包,进行格式解析,运用到命令行字典程序中
curlconverter.com/#go //用于把从浏览器中截取到的curl字符串,生成相应的go代码,用于求取该curl字符串
oktools.net/json2go //可以把JSON转Golang Struct可以接受上述的网站生成代码的数据
再筛选出解析后的数据中需要的字段,最后打印
socket5代理服务器
王克纯大佬的github仓库源码
先了解了socket5代理服务器的原理,以及使用范围
socks5 相当于在防火墙开了个口子,让授权的用户可以通过单个端口去访问内部的所有资源。实际上很多翻墙软件,最终暴露的也是一个 socks5协议的端口。
使用了go语言内置的net包创建一个简易转发服务器,再继续扩展其功能
然后通过客户端对其传输数据,socket5代理服务器进行解析,再去访问真正的服务器,把资源返回,socket5代理服务器再返回资源给客户端
资源返回有个语法,个人认为比较关键:context的WithCancel的使用
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
go func() {
_, _ = io.Copy(dest, reader)
cancel()
}()
go func() {
_, _ = io.Copy(conn, dest)
cancel()
}()
<-ctx.Done()
- WithCancel()函数接受一个 Context并返回其子Context(上图ctx)和取消函数cancel
- 新创建协程中传入子Context做参数(上图是匿名函数,自动捕获外部变量),且需监控子Context(上图ctx)的Done通道,若收到消息,则退出,未收到就会阻塞
- 需要新协程结束时,调用 cancel 函数,即会往子Context(上图ctx)的Done通道发送消息
- 注意:当父Context的 Done() 关闭的时候,子Context的 Done() 也会被关闭