好是池塘清梦处,Go引春草入新诗

本文探讨了Go语言的简单性,包括语言特性少带来的快速选择和gofmt带来的代码风格统一,强调了可读性的重要性。Go的类型安全、并发特性以及不采用继承的独特设计得到了赞赏。尽管缺乏泛型,但Go通过其他方式实现了代码复用。并发是Go的一大亮点,其goroutines简化了多任务处理。文章还提到了Go在类型安全和减少心智负担方面的贡献。
摘要由CSDN通过智能技术生成

偶然间,听闻有同学转Java为Go,我也起了好奇心,遂想弄一弄Go

首先从简单性谈起吧!

Simple?

什么是简单?我的理解就是——语言特性少。那么具体而言会带来什么好处呢?

快速选择不必纠结

一个特性特别臃肿的语言,往往会存在这样一个问题,就是我们有很多种特性可以选择,却时常陷入选择困难症,不知道如何选择,而这个时候Go语言却说,对不起你没有选择!毫无疑问这确实让事情变得简单了。

可是真的是这样吗?让我们陷入选择困难症的关键真的是语言特性太多了吗?至少从我的经验来说不是这样的。语言特性当然很多,可是作为一个写代码已久的程序员总有自己所偏好的特性,那这样对于程序员来说其实这门从语言特性角度来看是臃肿的语言,却在程序员的心智中是简单的。(当然这对于防止高手炫技以及新手入门是很友好的)

Go语言另一个能减少这种纠结的特点就是引入了gofmt,直接将gopher的代码风格选择限定在一个最小区间。虽然有人会对这个深恶痛绝,但我还是挺喜欢的。

可读性更高

我在大一上C语言课的时候常常被++和赋值两个operator的组合所困扰,实在不知道是先该赋值,还是先该自增。而在这里go便做的很好。go虽然也有++,可是赋值和++是不能那么恶心的组合的。所以从这个角度来说可读性提高是完全可以肯定的。

可是重点在于有多高?让一段代码可读性极低的重点是在什么地方呢?恐怕并不是语言特性臃肿。而是注释、代码习惯以及代码逻辑本身。

可读性的问题主要是作者的问题,其次是读者,最后才是语言。

Simplicity is Complicated

世界的本质是复杂,简单不过是对复杂的隐藏——前半句是我在《设计心理学》看到的,后半句来自参考文献[1]

而最根本的简单来自于人认知的简单。所有的简单都要归结到人身上——人的使用,人的感受,人的反思。——我说的

设计中往往有一种很普遍的误区——他们认为简单就是更少的配色,更少组件,以及更“简洁”的视觉冲击,可是却不知道把人放到哪里去了。我曾经买过一个很简单的鼠标,配色绝对简洁,外观也绝对简洁,可惜完全就不是给人的手使用的。

程序也是如此,不过程序的主要使用者是心智而已。所以谁能最大化减轻程序员的心智负担,谁就能称之为简单。Go在很多地方都做到了。一个很典型的例子就是goroutines,程序员不需要考虑什么stack size,返回完成状态,也没有id。这不仅不需要考虑太多东西,而且代码行数也足够简单。

另一个例子

另一个例子暂时没有

独特

Go绝对独特。这是我喜欢Go的最主要原因。

如果说Go的哲学-社区/规模足够大和完善是吸引的一个钩子的话,那么独特才能让却是让人真正为它流连忘返的地方。

这也许也是中小语言一种很好的策略吧!作为像Java,Javascript,C那些大语言,为了控制风险,满足众多的需求,大而全几乎是必然的。

如果中小语言也学大语言搞什么大而全,这岂不是拿自己的短处去碰大语言的长处吗?所以要独特,要成为缝隙市场的王者,然后弯道超车。Go显然便是这样的。

继承

在不同文化下,不同语言所具有的结构、意义和使用等方面的差异,在很大程度上影响了使用者的思维方式–沃尔夫假说

从一个常写Java,python之类面向对象语言转到Go的时候,一个最直观的感受就是——没对象😜。

没对象是一件很难受的事情,尤其对那种一直有对象的人而言(不是我😏)。不过这并不致命,虽然有很多材料把对象说的神乎其神,可是说到底在代码上就是一堆数据和方法的集合,这个Go同样也可以做到。

伴随着没有对象的另一个后果就是无法继承。继承有两个目的,一个是代码复用,这个并不是一定需要继承,组合也能做到。另一个是多态,这是使用继承的关键所在。

如果go想做到类似于多态做到的那些功能的话,我想到了一种方法,找到了一种方法。一个是使用if else这种分支判断数据类型,然后做出相应的操作。可是这比之面向对象语言的多态还是差了一些,因为如果要更改的话,不仅相应的对象要改,也要在if else里面增加代码。

另一种方法是我从go语言中文网找到的,就是将实现同一个接口的结构传入slice这种内置数据结构中。

类型置后

这也是一个非常直观就能看得到的不同。知乎答主那罗延认为这可能是因为为了写解释器或者编译器的便利,把他们parse成一个tree,tree的后半部分让他们可以被缺省。

并发

只有并发才是Go中最具独特,也是在我看来真正称之为非常有用且简单的特性。

现在没有时间对go并发做更多深入的了解,所以这一块暂时空着。

其他

强类型

动态弱类型曾经是我在接触python时最喜欢的特性,而今我只能说Go做的很好,强类型非常棒!

动态一时爽,重构火葬场——知乎许镇

关键字

接口实现不使用关键字真的好吗?type关键字难道不多余吗?

泛型

泛型是Go语言缺少的另一个我常常在Java上使用的特性,可是然而当我写到这里的时候,我发现我根本找不到我为什么要用泛型的理由,我只是在用,所以我通过万能的search engine,找到了我为什么应该使用泛型的原因

  1. 可重用性

    func ReverseInts(s []int) {
        first := 0
        last := len(s) - 1
        for first < last {
            s[first], s[last] = s[last], s[first]
            first++
            last--
        }
    }
    
    func ReverseStrings(s []string) {
        first := 0
        last := len(s) - 1
        for first < last {
            s[first], s[last] = s[last], s[first]
            first++
            last--
        }
    }
    
    // 试想一下,两个除了参数类型完全一样的代码,这会有多么地糟糕!
    // copy from https://www.oschina.net/news/108697/why-golang-generic
    
  2. 类型安全

    用不上类型的强制转换,而且一旦声明了何种类型的集合就不再允许其他类型加入。

    在Java没有泛型以前,Colletion对元素类型是没有任何限制的。所以即使需要装的是Dog,可是把Cat对象存储到Collection中也不会有任何编译上的问题,直到… 运行到了那里。

    这和我之前在python动态变量碰到的问题是类似的,别人需要的是int类型,可是我却将其当作了str类型,这在编译时没有任何问题,直到我调用了那个api

    不过对于Go来说没有了继承也谈不上类型安全问题😂。(事实上他可能提供了比我们想象中更严格的类型安全。)

最后…闲言碎语

这是我感觉写的比较爽的博客,不过因为现在时间比较紧,所以很多东西都没有涉及到,尤其是我特别喜欢的并发部分。

[1] https://talks.golang.org/2015/simplicity-is-complicated.slide#1

[2] https://studygolang.com/articles/12907

[3] https://tonybai.com/2017/04/20/go-coding-in-go-way/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值