前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Golang 受欢迎的原因:大道至简

Golang 受欢迎的原因:大道至简

作者头像
用户2937493
发布2019-08-29 14:27:37
4900
发布2019-08-29 14:27:37
举报
文章被收录于专栏:米奇爱编程米奇爱编程

前言

Golang自2009年发布第一个版本,2012年发布1.0版本。在这10年的时间里,不断有开发者加入Golang的阵营中,不断共建Golang生态。其中比较有代表性的Golang编写软件作品是Docker和Kubernetes。从目前Golang的发展时间和社区活跃度来看,Golang无疑是一门成功的编程语言。

大道至简

有次微信公开课中,微信之父张小龙提到微信成功的秘诀就是简单,把所有功能做到最简单,UI最简单,用户使用最简单。这样使得竞品无法抄袭,因为微信是最简单的,对手加了一点东西都是冗余。那么什么使得Golang这么成功呢?

你可能会提到下面的原因:

  • 编译速度快
  • 执行速度快
  • 部署无依赖
  • 工具齐全
  • 官方库和第三方开源库丰富

但是这些不是语言特性,全都非常重要但是不是真正的答案。比较少谈起的是:接口或者并发这样真正的语言特性。真正的原因是简单。Golang是简单的,至少相比于当前的编程语言来说是简单的。简单有很多面,简单同时也是复杂的。语言使用上的简单对应的肯定是底层实现原理的复杂,和设计人员的精美设计的结果。

其他编程语言

Java,JavaScript,C#,C++,PHP,Python 这些编程语言积极的互相借鉴语言特性,例如这些语言都会有class(类)。它们正在汇总为一个简单的大型语言

编程语言需要不同的维度考虑:

逻辑编程(logic programming)

过程编程(procedural programming)

函数编程(functional programming)

面向对象编程(object-oriened programming)

并发编程(concurrent programming)

如果所有的编程语言都汇总在一起,那么我们思考的编程模式就会是一样的。但是有不同的思考方式是好的,需要不同的编程语言解决不同的问题。我们要的不是仅仅只有一个工具,而是一堆工具,不同的工具聚焦解决不同的问题。前面提到的语言,如Java8,C++14正在讨论新的特性,这些语言通过加入特性在不断的竞争。当某个语言出现了某个特性时,另外的语言一定会跟随,例如C++11/14加入的类型推导,不由得让人想起了脚本语言Python。这些语言在发展的过程会变得越来越复杂,同时也会变得越来越相似。它们会膨胀得没有区分度。

Golang

Golang没有尝试像其他编程语言,不在特性上竞争。Golang 1.0版本发布时,这门语言的特性就已经固定了。很多Golang的新手会要求Golang具有一些他们知道的其他编程语言的特性。但是这些特性不属于Golang,这门编程语言的特性已经固定了。加入新特性不会使Golang变得更好,只会使它变得更大,更臃肿。

可读性

如果一门编程语言有太多特性,你会浪费时间在挑选用哪个的问题上。然后实现,精简,可能会回想和重做。

实际工作中,经常会发生的一幕是,有人会问,“为什么这些代码要这样写,这段代码是怎么工作的”,这个人可能是其他人,更有可能是你自己。这些代码是很难简单的能理解到,因为它用了一个更加复杂的编程语言,由于复杂编程语言的诸多特性,可能会导致很多分支的结果,所以我们需要分析这段代码的各种可能性,一不小心就会掉到坑里面。所以对于程序员来说,更倾向于只有一种实现方法,或者至少应该是尽量少的实现方法,更简单的实现方法。更多的特性会增加编程语言的复杂度,我们想要简单的编程语言。更多的特性会让可读性受损,我们想要可读性。可读性是最重要的。因为可读性意味着可靠性,如果你能够读懂代码和它意味着什么,就会很容易明白它的工作原理。如果它出现问题也会更容易修复。

设计理念

简单的交互方式是简单的特性。简单是Golang的目标。

Golang实际上实现原理非常复杂,但是它看起来很简单,使用很简单。语法非常简单和准确,没有歧义,没有惊喜。这需要Golang的创始人/团队经过大量的设计、实现和优化。所以简单是掩盖复杂的一门艺术。

下面会介绍Golang的几个简单特性:Gc机制(垃圾回收),goroutine,interface(接口),package(包)。每个简单的特性后面都是复杂的实现。

垃圾回收

垃圾回收可能是最好的用简单掩盖复杂的特性。实现起来非常难,但是很值得。因为有gc机制我们Golang代码编写得更简单。写代码的时候不需要关心“拥有者”。

并发

Golang原生就支持了并发,而不是依赖第三方库。Golang并发包括下面三个元素:goroutines(执行体),channels(通信),select(协调)。

这里我们只需要暂时先关注goroutine,通过go function(args)启动一个独立运行的goroutine。三个字符’g’ ‘o’ ‘ ’就能启动一个goroutine。很难做到比这更简单的了。和gc机制一样,将编程人员需要关心的东西最小化。栈的大小,返回值和完成状态,线程 ID等都不用关心。虽然goroutine的实现很复杂,依赖于gc机制和栈管理,但是编程人员不用关心这些,只需要go就能启动一个goroutine。

接口

接口仅仅是方法的集合,没有数据。很简单的想法。

代码语言:javascript
复制
type Reader interface {

       Read([]byte)(int, error)

}

var r Reader = os.Stdin //静态检查

var x interface{} = os.Stdin //静态检查

r = x.(Reader) //动态检查,一定要是精准断言,否则会panic

在静态类型语言中加入动态类型转换,这些需要小心精准的设计。接口的赋值在运行时完成。最好是用“comma, ok”的语法,否则失败会panic。接口是Golang最有区分度和最强大的特性。深度影响了包的设计。另外包允许组合,例如可以将io.Reader和io.Writer组合为io.ReadWriter。感觉很简单,实则底层原理很复杂。

一个结构化程序和库的设计。

代码语言:javascript
复制
package big

…

import “math/big”

包的设计花费了Golang团队大量时间去设计。允许组合,可扩展,共享,数据隐藏(大小写),还有隔离 …。包的设计涉及到程序的设计,语法,命令,编译,链接,测试等等。但是对于Golang编程人员来说只需要使用package定义包,用import引用包即可。这也是用简单掩盖复杂的一个例子。

上述的示例都是为了说明Golang使用是非常简单,实现非常复杂。作为Golang的使用者,我们只需要清楚它的使用即可,而无需关心Golang的复杂实现,这也是Golang团队的目标。

下面是一个简单的Golang程序:

代码语言:javascript
复制
package main

import (
    "fmt"
    "log"
    "net/http"
)

func 你好_Gophers(w http.ResponseWriter, req *http.Request) {
    fmt.Fprintf(w, "你好 Gophers!\n")
}

func main() {
    http.HandleFunc("/", 你好_Gophers)
    err := http.ListenAndServe("localhost:12345", nil)
    if err != nil {
        log.Fatal("ListenAndServer:", err)
    }
}

掩盖了下面的复杂过程:

Unicode和UTF8处理

包的引用和使用

Fprintf直接对接网络连接

函数作为参数传递(HandleFunc)

真正的并发 —server并没有阻塞

总结

Golang是使用简单,底层实现原理复杂的一门编程语言。

参考

https://www.youtube.com/watch?v=cQ7STILAS0M

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-07-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 大道至简
  • 其他编程语言
  • Golang
    • 可读性
      • 设计理念
        • 垃圾回收
          • 并发
            • 接口
              • 总结
              • 参考
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档