go语言编程模式
文章目录
go语言编程模式总结
面向对象最佳实践
|
|
Square 并没有实现 Shape 接口的所有方法,程序虽然可以跑通,但是这样的编程方式并不严谨,如果我们需要强制实现接口的所有方法,那该怎么办呢?
在 Go 语言编程圈里,有一个比较标准的做法:
|
|
声明一个 _ 变量(没人用)会把一个 nil 的空指针从 Square 转成 Shape,这样,如果没有实现完相关的接口方法,编译器就会报错:
这样就做到了强验证的方法。
时间性能问题
Go 语言是一个高性能的语言,但并不是说这样我们就不用关心性能了,我们还是需要关心的。下面我给你提供一份在编程方面和性能相关的提示。
- 用 Itoa 而不是 sprintf
- 避免 String 转 []byte
for-loop
对某个slice使用 append,请扩容到尾,避免重新分配内存,浪费内存- 用stringBuild 拼接字符串,效率比 + 或者 += 高
- 使用 协程,用sync.WaitGroup 来同步分片操作。
- 避免在热代码进行内存分配,导致gc很忙,尽量用
sync.Pool
重用对象 - lock-free 的操作,避免使用 mutex,尽量使用 sync/atomic包
- 使用I/O缓冲, I/O 是个非常慢的操作,使用
bufio.NewWrite()
和bufio.NewReader
可以带来更高性能。 for-loop
里面固定的正则表达式,使用 regexp.Compile 编译表达式,性能可以提高。
异常处理
error 实现 Cause 接口,这样就可以 获取根因。
|
|
Functional Options 编程模式
这是一个函数式编程的应用案例,编程技巧也很好,是目前 Go 语言中最流行的一种编程模式。‘
|
|
针对这样的对象配置,我们需要有多种不同的创建不同配置 Server 的函数签名,如下所示:
|
|
因为 Go 语言不支持重载函数,所以,你得用不同的函数名来应对不同的配置选项。
我们可以使用 Builder 模式 ,对这个对象添加很多的 withOptions 方法, 然后就可以链式编程。
|
|
但是这样自己要写一个 额外的 builder类,另一种比较好的方法就是 funtional Options 可以省掉 builder 这个结构体
|
|
这种写法的好处:
直觉式的编程;高度的可配置化;很容易维护和扩展;自文档;新来的人很容易上手;没有什么令人困惑的事(是 nil 还是空)。
Map reduce 模式
其实,在全世界范围内,有大量的程序员都在问 Go 语言官方什么时候在标准库中支持 Map、Reduce。Rob Pike 说,这种东西难写吗?还要我们官方来帮你们写吗?这种代码我多少年前就写过了,但是,我一次都没有用过,我还是喜欢用“For 循环”,我觉得你最好也跟我一起用 “For 循环”。
目前并没有太好的实现和做法。。
修饰器模式
|
|
可以看到,我们动用了一个高阶函数 decorator(),在调用的时候,先把 Hello() 函数传进去,然后会返回一个匿名函数。这个匿名函数中除了运行了自己的代码,也调用了被传入的 Hello() 函数。这个玩法和 Python 的异曲同工,只不过,有些遗憾的是,Go 并不支持像 Python 那样的 @decorator 语法糖。所以,在调用上有些难看。 先看一个简单的 HTTP Server 的代码:
|
|
多个修饰器的 Pipeline在使用上,需要对函数一层层地套起来,看上去好像不是很好看,如果需要修饰器比较多的话,代码就会比较难看了。不过,我们可以重构一下。重构时,我们需要先写一个工具函数,用来遍历并调用各个修饰器:
|
|
文章作者 lyr
上次更新 2022-05-11