最近学习 Go,可是苦于没有项目练手,因而便逼迫本身:若是想到什么有趣的东西,看能不能用 Go 实现一遍,因而便有了这篇流水文。bash
归并排序中的 merge 函数,相信每一个人都很熟悉,网上随便搜搜都有一大堆文章,这里再也不赘述细节。一开始,我用的是常规套路,不过以为没啥意思,无非是「换汤不换药,感受仍是在拿本身熟悉的语言写东西」。数据结构
联想到 Go 的 channel 彷佛能在某种程度上知足个人要求,再加上 Goroutine 这种东西,便想:是否是也能利用利用这两个语言特性。函数
channel 这个数据结构,在 Go 中有比较丰富的含义,但我基本上把它当队列使用。Goroutine 也同样,我基本把它等同于「用户态线程」(二者都很牛逼,不过做为应用层的开发者,有时候并不想深究太多,一切都往简单方向理解)。学习
因为我只是练手,因此我想到的 API 长这样:ui
Merge(ch1, ch2): outChan
复制代码
给定两个有序的 channel,而后将其合并为一个有序的 channel。spa
因而个人实现以下:线程
func Merge(ch1 <-chan int, ch2 <-chan int) <-chan int {
out := make(chan int)
go func() {
// 等上游的数据 (这里有阻塞,和常规的阻塞队列并没有不一样)
v1, ok1 := <-ch1
v2, ok2 := <-ch2
// 取数据
for ok1 || ok2 {
if !ok2 || (ok1 && v1 <= v2) {
// 取到最小值, 就推到 out 中
out <- v1
v1, ok1 = <-ch1
} else {
out <- v2
v2, ok2 = <-ch2
}
}
// 显式关闭
close(out)
}()
// 开完goroutine后, 主线程继续执行, 不会阻塞
return out
}
复制代码
语法近乎简陋。不过对我而言并没有大碍,反而喜欢。不太喜欢语法特性(语法糖)太多的语言,乱糟糟的,分散了太多注意力。要是每一个语法特性都是相互正交的,我天然双手赞同,可是若是多个特性都在作同一件事情,通常对学习者的负担比较大的(Ruby),也不利于合做。code
编译型。很少讲,几乎已是俺学习新语言的必要条件了,前期开发效率可能会慢点,可是换来的是更少的 bug,尤为是对团队协做,能够减小不少痛苦。(要是你团队里面都是高手,用 Python 天然是爽歪歪,可是这一条件并不老是知足。因此仍是使用能编译的语言吧 :))排序