Go语言精进自学系列 | 使用Go语言原生编码思维来写Go代码
书籍来源:《Go语言精进之路:从新手到高手的编程思想、方法和技巧》
一边学习一边整理读书笔记,并与大家分享,侵权即删,谢谢支持!
附上汇总贴:Go语言精进自学系列 | 汇总_COCOgsta的博客-CSDN博客
在编写一些Go代码之后,很多人感觉自己写的Go代码很别扭,并且总是尝试在Go语言中寻找自己熟悉的上一门语言中的语法元素。出现这种情况的主要原因是大脑中上一门编程语言的思维方式在“作祟”。那么思维与语言之间究竟有什么联系呢?
4.1 语言与思维——来自大师的观点
在编程语言界,首届图灵奖得主、著名计算机科学家艾伦·佩利(Alan J.Perlis)提出:“不能影响到你的编程思维方式的编程语言不值得学习和使用。”
4.2 现实中的“投影”
问题描述:素数是一个自然数,它具有两个截然不同的自然数除数:1和它本身。这里的问题是如何找到小于或等于给定整数n的素数。针对这个问题,我们可以采用埃拉托斯特尼素数筛算法。
算法描述:先用最小的素数2去筛,把2的倍数筛除;下一个未筛除的数就是素数(这里是3)。再用这个素数3去筛,筛除3的倍数……这样不断重复下去,直到筛完为止(算法图示见图4-1)。
图4-1 素数筛算法图示
下面是该素数筛算法的不同编程语言的实现版本。
(1)C语言版本
// chapter1/sources/sieve.c
#include <stdio.h>
#define LIMIT 50
#define PRIMES 10
void sieve() {
int c, i,j,numbers[LIMIT], primes[PRIMES];
for (i=0;i<LIMIT;i++){
numbers[i]=i+2; /*fill the array with natural numbers*/
}
for (i=0;i<LIMIT;i++){
if (numbers[i]!=-1){
for (j=2*numbers[i]-2;j<LIMIT;j+=numbers[i])
numbers[j]=-1; /* 筛除非素数 */
}
}
c = j = 0;
for (i=0;i<LIMIT&&j<PRIMES;i++) {
if (numbers[i]!=-1) {
primes[j++] = numbers[i]; /*transfer the primes to their own array*/
c++;
}
}
for (i=0;i<c;i++) printf("%d\n",primes[i]);
}
复制代码
(2)Haskell版本
// chapter1/sources/sieve.hs
sieve [] = []
sieve (x:xs) = x : sieve (filter (\a -> not $ a `mod` x == 0) xs)
n = 100
main = print $ sieve [2..n]
复制代码
(3)Go语言版本
// chapter1/sources/sieve.go
func Generate(ch chan<- int) {
for i := 2; ; i++ {
ch <- i
}
}
func Filter(in <-chan int, out chan<- int, prime int) {
for {
i := <-in
if i%prime != 0 {
out <- i
}
}
}
func main() {
ch := make(chan int)
go Generate(ch)
for i := 0; i < 10; i++ {
prime := <-ch
print(prime, "\n")
ch1 := make(chan int)
go Filter(ch, ch1, prime)
ch = ch1
}
}
复制代码
对比上述三个语言版本的素数筛算法的实现,我们看到:
C版本的素数筛程序是一个常规实现。它定义了两个数组numbers和primes,“筛”的过程在numbers这个数组中进行(基于纯内存修改),非素数的数组元素被设置为-1,便于后续提取。
Haskell版本采用了函数递归的思路,通过“filter操作集合”,用谓词(过滤条件)\a -> not $ a mod
x == 0筛除素数的倍数,将未筛除的数的集合作为参数传递归递给下去。
Go版本程序实现了一个并发素数筛,它采用的是goroutine的并发组合。程序从素数2开始,依次为每个素数建立一个goroutine,用于作为筛除该素数的倍数。
4.3 Go语言原生编程思维
面对同一个问题,来自不同编程语言的程序员给出了截然不同的方法:C的命令式思维、Haskell的函数式思维和Go的并发思维。我们可以得到一个未经理论证实但又确实对现实有影响的推论:编程语言影响编程思维,或者说每种编程语言都有属于自己的原生编程思维。
经验告诉我们,但凡属于某个编程语言的高质量范畴的代码,其必定是在这种编程语言原生思维下编写的代码。
那么Go原生编程思维究竟是什么呢?一门编程语言的编程思维是由语言设计者、语言实现团队、语言社区、语言使用者在长期的演进和实践中形成的一种统一的思维习惯、行为方式、代码惯用法和风格。
我们的目标是编写出高质量的Go代码,这就需要我们在学习语言的同时,不断学习Go语言原生的编程思维,时刻用Go编程思维考虑Go代码的设计和实现,这是通往高质量Go代码的必经之路。
相关文章
- go-dongle 0.2.5 版本发布,一个轻量级、语义化的 golang 编码解码、加密解密库
- 「Go工具箱」一个简单、易用的多错误管理包:go-multierror
- 从 Java 的角度看待 Go 的编码规范和性能调优| 青训营笔记
- 区块链生态系统将崩溃、Rust 超越 Go、无服务器成主导,这十大计算机预测将成真?
- Go语言go mod包依赖管理工具使用详解
- 使用Go语言来操作Oracle数据库(go语言oracle)
- 编程新精英:Go语言 Redis开发(go语言redis开发)
- Go语言连接Oracle数据库实战(go连接oracle)
- 深度探索Go语言与Redis结合(go-redis)
- Go语言环境配置:在 Linux 下实现(go环境搭建linux)
- 徒手用Go编写Redis迈向新技术世界的旅程(徒手用go写个redis)
- Go语言链接Oracle数据库的实践记录(go 链接oracle)
- 部署Go语言快速连接Oracle实现轻松部署(go连接oracle简单)
- Go语言快速安装Oracle数据库(go语言安装oracle)
- Go语言操作Oracle数据库技术实践(go操作oracle)
- 语言Oracle中发挥神奇作用的Go语言(oracle中有go)
- Redis集群搭建Go的艰难之路(redis集群搭建go)