这是我参与「第三届青训营 -后端场」笔记创作活动的第一篇笔记
Go 语言的优点
- 高性能,高并发
- 语法简单, 学习曲线平缓
- 丰富的标准库
- 完善的工具链
- 静态链接
- 快速编译
- 跨平台
- 垃圾回收
基础语法
Go语言的性能不言自明,而且拥有大量的第三方库,每个人都可以为Go做贡献,上手难度确实不高,语法上跟其他语言类似,有一些比较小的变化,需要把一些关键字放在后面,是可以像js一样实用var来定义变量。给我一种兼具C++和python的感觉。
学语言第一个程序都是Hello World,Go的输出需要实用fmt的包,Go语言我不喜欢的一点在于导包这里,用到什么包就导什么包,但是如果导了不用也会报错。
-
if else这就if else后面没有括号,但是if后面必须得有一个大括号。
-
循环,Go里只有for循环,格式上和C++的for循环不太一样,要求没那么严格,也可以使用break和continue。
-
switch,Go的switch比较有意思,他只执行一个case,不用break,而且case里可以使用各种类型的变量,这一点功能非常强大。
-
数组,这个没什么介绍的,跟C++差不多,固定长度,不方便。
-
slice,变长数组,类似python,但是不支持负数索引,append之后要赋值给原数组,因为可能会超过原来的大小,因为slice实际上是一个定长数组,但是他可以自动增加长度,可以使用make创建。
-
map,无序,key-value的形式,可以使用make创建空的map。
-
range,用来遍历map或者slice。
-
函数,使用func定义, 返回类型也是在函数名后面,可以返回到个值。
-
指针,跟C++类似
-
struct, 可以赋初值,可以使用指针,避免大结构体的开销。可以为结构体定义方法,类似于成员函数
type user strct{
name string
password string
}
func (u *user) resetPassword(password string){
u.password = password
}
- 错误处理,函数如果出错,返回nil和error,没有的话但会结果和nil。
func findUser(users []user, name string) (v *user, err error) {
for _, u := range users {
if u.name == name {
return &u, nil
}
}
return nil, erroe.New("Not Found")
}
//使用
if u, err := findUser([]user({"string","1234"}), "123"); err != nil {}
else {}
-
strings, 一些常用的操作,类似python。
-
格式化输出,类似C的printf函数,但是可以使用%v,不区分变量类型,%+v打印详细信息,%#v更详细的信息。
-
JSON,每个字段的首字母大写,JSON.marshaler序列化,JSON.unmarshaler反序列化,json tag修改输出格式。JSON的功能还是很强大的。
type Product struct {
Name string `json:"name"`
ProductID int64 `json:"-", omitempty` // 表示不进行序列化 忽略空值或者0值
Number int `json:"number"`
Price float64 `json:"price", number` //指定类型
IsOnSale bool `json:"is_on_sale,string"`
}
-
时间 time.Now()获取当前时间,time.Date()构造带时区的时间,now.Unix()获取时间戳。t.Year()获取年份
-
数字解析, 在strconv包下, ParseFloat()和Atoi()等。
-
进程信息,os.Getenv()获取环境变量,os.Args()获取命令里的参数,类似C++的main函数的argv,其他的不太懂,exec.Command()
猜数游戏
rand.Seed(time.Now().UnixNano())//随机数种子
rand.Intn(max) //[0,max)的随机数
reader := bufio.Newreader(os.Stdin)//输入
input, err := reader.ReadString('\n')
input = strings.TrimSuffix(input, "\n")//去掉\n的后缀
在线词典
代码生成工具:curlconvert.com/#go ,根据curl命令生成代码支持多种语言。
request和response可以使用struct来定义字段使用JSON来序列化和反序列化进行发送和接收数据。
json转结构体:oktools.net/json2go ,根据返回的JSON生成对应的Go结构体。
socks5代理
socks5的原理就不说了,直接看代码。这里感觉Go在网络这方面做的很方便。
server, err := net.Listen("tcp", "127.0.0.1:1080")//监听端口
client, err := server.Accept()//接受请求,返回连接
go process(client) //go代表启动goroutine,开销小
func process(conn net.Conn) {
defer conn.Close()//函数结束释放连接
//处理
}
接下来是认证阶段,三个字段,VER: 协议版本,socks5为0x05, NMETHODS: 支持认证的方法数量, METHODS: 对应NMETHODS,NMETHODS的值为多少,METHODS就有多少个字节。RFC预定义了一些值的含义,内容如下: X’00’ 不需要认证 X’02’ 用户密码 请求阶段,得到URL或者ip+port。 建立连接,双向收发数据,net.Dial()建立TCP连接。io.Copy()实现单项数据转发,双向要建立两个。
结束语
Go的基础语法也都大差不差的了解了,第三个这个socks5代理这个我觉得真不基础,可能我不太了解这块,觉得挺难的。慢慢来吧!Go在网络上还有JSON这方面的性能都很好,可能以后会继续学习。