go语言_go语言编程 - CSDN
go语言 订阅
Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。 展开全文
Go(又称 Golang)是 Google 的 Robert Griesemer,Rob Pike 及 Ken Thompson 开发的一种静态强类型、编译型语言。Go 语言语法与 C 相近,但功能上有:内存安全,GC(垃圾回收),结构形态及 CSP-style 并发计算。
信息
发布于
2009年
最新版本
1.14
发布组织
Google
中文名
Golang
属    性
编程语言
外文名
Golang
go简介
Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言。罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pike)及肯·汤普逊(Ken Thompson)于2007年9月开始设计Go,稍后Ian Lance Taylor、Russ Cox加入项目。Go是基于Inferno操作系统所开发的。Go于2009年11月正式宣布推出,成为开放源代码项目,并在Linux及Mac OS X平台上进行了实现,后来追加了Windows系统下的实现。在2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”。 目前,Go每半年发布一个二级版本(即从a.x升级到a.y)。 [1] 
收起全文
精华内容
参与话题
  • GO语言零基础入门最佳教程

    千人学习 2019-06-26 17:43:41
    出身名门、血统纯正的Go语言于2012年正式面世。静态语言、函数多返回值、天生并发、自动垃圾回收、安全性高、语法简单、编译快速这几个方面的特性提炼出Go的三个高富帅的标签:运行快、开发快和部署快。本视频...
  • Go语言简介

    千次阅读 2019-04-03 09:43:16
    我身边有位朋友一直和我说:"go语言很好,真的很好呀,很容易上手的,性能又好,又很轻便,要不要一起学呀?"。 经过: 我简单地翻看了菜鸟教程,对go有了初步了解,确实和朋友描述的一致,仿佛打开了新世纪的大门...

    我为什么学习Go这门语言?

    背景:

    我身边有位朋友一直和我说:"go语言很好,真的很好呀,很容易上手的,性能又好,又很轻便,要不要一起学呀?"。

    经过:

    我简单地翻看了菜鸟教程,对go有了初步了解,确实和朋友描述的一致,仿佛打开了新世纪的大门,感觉这门语言很适合我这种嫌麻烦的懒人,初步对这门语言有了一定的兴趣。

    结果:

    偶然有一天,看了一篇关于2019年最值得学习的语言TOP3里面又提到了GO语言,并且讲述了当前这个语言的受欢迎程度和普及度越来越高,越来越多的开发者和企业开始使用该语言,就这样,坚定了我学习go语言的决心。

     

    一、什么是go语言

    Go(又称Golang)语言是Google公司开发的一种静态型、编译型并自带垃圾回收和并发的编程语言。

    官网:https://golang.org/

    历史概要:

    (1)于2007年9月由罗伯特·格瑞史莫,罗勃·派克(Rob Pike)及肯·汤普逊开始设计,稍后Ian Lance Taylor、Russ Cox加入项目

    (2)于2009年11月正式宣布推出,并成为开放源代码项目,因此Go开发团队将 2009 年 11 月 10 日(即该语言正式对外开源的日子)作为其官方生日,并在Linux及Mac OS X平台上进行了实现,后来追加了Windows系统下的实现

    (3)2012年3月28日正式发布go1.0版本

    (3)2016年,Go被软件评价公司TIOBE 选为“TIOBE 2016 年最佳语言”

    (4)如今,Go每半年发布一个二级版本(即从a.x升级到a.y),现最新版本为Go1.12(于2019/02/25发布)

     

    二、go语言特点

    1、上手快,语法简单,我只花了一晚上便对基本语法有了一定的了解,我觉得大概一周左右的时间应该可以用它来解决一些实际问题了

    2、编译输出可执行文件,go语言可以直接输出为目标平台的原生可执行文件,此外,go语言还可以编译输出能导入c语言的静态、动态库,同时go1.7版本开始,go语言支持将代码编译成插件。

    3、工程结构简单,无须头文件,编译文件均来自于后缀名为go的源码文件,无须解决方案、工程文件、Make File等,只要将工程文件按照GOPATH的规则进行填充即可。

    4、编译速度快,go语言利用自己的特性实现并发编译,最开始并发编译的最小元素是包,从go1.9版本开始,最小并发编译元素缩小到函数,整体编译速度提高20%,而且由于其工程结构的简单,在很大程度上加速了编译的过程。

    5、高性能,语言性能上和java相近,但在某些方面表现方面不如java

    6、原生并发支持,无须第三方库,go语言的并发基于goroutine,类似于线程,但并非线程,可以理解为一种虚拟线程。go语言运行时会合理参与调度goroutine,并将goroutine合理分配到各个cpu中,最大限度地使用cpu性能

    7、性能分析,安装go语言的开发包后,使用go语言的工具链可以直接进行go语言的代码性能分析

    8、强大的标准库,涵盖网络、系统、加密、编码、图形等方面

    9、代码风格清晰、简单:

    1)去掉循环冗余的括号

    for(int i = 0; i < 10; i++) {

    }

    =>

    for i := 0; i < 10; i++ {

    }

    2)去掉表达式冗余的括号

    if (i > 0) {

    }

    =>

    if i > 0 {

    }

    3)强制的代码风格,左括号必须紧接语句不换行,具体如1)、2),否则视为代码编译错误,此外,go语言还提供了一套代码格式化工具

    4)不用再纠结于i++和 ++i,对于go语言而言,自增操作不再是一个操作符,而是一个语句,因此go语言中只有i++一种写法

     

    三、使用go语言的项目

    1、Docker,是一种操作系统层面的虚拟化技术,可以在操作系统和应用程序之间进行隔离,也可以称之为容器。

    2、golang,也就是go,go早起源码由c和汇编进行编写,从1.5版本自举后,完全使用go语言自身进行编写。

    3、kubernetes,google公司构建于docker之上的容器调度服务。

    4、etcd,一款分布式、可靠的kv存储系统

    5、beego,一个极轻量级、高伸缩行和高性能的web应用框架

    6、martini,一款快速构建模块化的web应用的web框架

    7、codis,国产的优秀分布式redis解决方案

    8、delve,go语言的强大调试器,被很多集成环境和编辑器整合

     

    本篇文章主要对go语言进行简单的介绍,包括其历史、特点及其在实际项目中的使用,下篇文章将和大家介绍go语言的开发环境的搭建。

     

     

     

     

     

     

     

     

     

     

    展开全文
  • Go语言入门之——基本了解

    千次阅读 2018-08-15 10:22:43
    Go语言基础 一、简介 (2)golang语言特性 2.1. 垃圾回收 内存自动回收,再也不需要开发人员管理内存 开发人员专注业务实现,降低了心智负担 只需要new分配内存,不需要释放 2.2. goroute天然并发 从语言...

    Go语言基础

    一、简介

    (1)什么是go语言?

    2007年,受够了C++煎熬的Google首席软件工程师Rob Pike纠集Robert Griesemer和Ken Thompson两位牛人,决定创造一种新语言来取代C++, 这就是Golang。出现在21世纪的GO语言,虽然不能如愿对C++取而代之,但是其近C的执行性能和近解析型语言的开发效率以及近乎于完美的编译速度,已经风靡全球。特别是在云项目中,大部分都使用了Golang来开发,不得不说,Golang早已深入人心。而对于一个没有历史负担的新项目,Golang或许就是个不二的选择。

    被称为GO语言之父的Rob Pike说,你是否同意GO语言,取决于你是认可少就是多,还是少就是少(Less is more or less is less)。Rob Pike以一种非常朴素的方式,概括了GO语言的整个设计哲学–将简单、实用体现得淋漓尽致。

    很多人将GO语言称为21世纪的C语言,因为GO不仅拥有C的简洁和性能,而且还很好的提供了21世纪互联网环境下服务端开发的各种实用特性,让开发者在语言级别就可以方便的得到自己想要的东西。

    • 1.1、发展历史

      2007年9月,Rob Pike在Google分布式编译平台上进行C++编译,在漫长的等待过程中,他和Robert Griesemer探讨了程序设计语言的一些关键性问题,他们认为,简化编程语言相比于在臃肿的语言上不断增加新特性,会是更大的进步。随后他们在编译结束之前说服了身边的Ken Thompson,觉得有必要为此做一些事情。几天后,他们发起了一个叫Golang的项目,将它作为自由时间的实验项目。

    2008年5月 Google发现了GO语言的巨大潜力,得到了Google的全力支持,这些人开始全职投入GO语言的设计和开发。

    2009年11月 GO语言第一个版本发布。2012年3月 第一个正式版本Go1.0发布。

    2015年8月 go1.5发布,这个版本被认为是历史性的。完全移除C语言部分,使用GO编译GO,少量代码使用汇编实现。另外,他们请来了内存管理方面的权威专家Rick Hudson,对GC进行了重新设计,支持并发GC,解决了一直以来广为诟病的GC时延(STW)问题。并且在此后的版本中,又对GC做了更进一步的优化。到go1.8时,相同业务场景下的GC时延已经可以从go1.1的数秒,控制在1ms以内。GC问题的解决,可以说GO语言在服务端开发方面,几乎抹平了所有的弱点。

    在GO语言的版本迭代过程中,语言特性基本上没有太大的变化,基本上维持在GO1.1的基准上,并且官方承诺,新版本对老版本下开发的代码完全兼容。事实上,GO开发团队在新增语言特性上显得非常谨慎,而在稳定性、编译速度、执行效率以及GC性能等方面进行了持续不断的优化。

    (2)golang语言特性

    • 2.1. 垃圾回收

      • 内存自动回收,再也不需要开发人员管理内存
      • 开发人员专注业务实现,降低了心智负担
      • 只需要new分配内存,不需要释放
    • 2.2. goroute天然并发

      • 从语言层面支持并发,非常简单

      使用一个go则在编译时会自动开启一个线程来执行后面的命令/函数/方法,不用像python需要先调用thread模块来开启线程

      • goroute,轻量级线程,创建成千上万个goroute成为可能
      • 基于CSP(Communicating Sequential Process)模型实现
    • 2.3. goroute线程之间的数据通信——管道

      使用go可以创建一个轻量级的goroute线程,线程之间如何通信,共享数据呢?答案是:使用管道来进行通信。管道需要定义并创建后,才能使用

      定义一个管道:

      var my_pipe chan int
      //my_pipe为管道名,chan为管道关键字表示定义的是一个管道,int表示管道内存储的数据类型

      创建一个管道:

      my_pipe = make(chan int,10)
      //make关键字表示开辟一个内存空间,第一个参数表示创建一个管道,10表示管道能存储的数据类型个数,如果超出则阻塞

      定义和创建可以合并写

      my_pipe := make(chan int,10)

      管道的定义和使用范例:

      //goroute线程之间使用管道进行数据通信
      
      func main() {
      go pi_pie()
      }
      
      func pi_pie() {
        pipe := make(chan int, 10) //make关键字创建一个管道(关键字chan),管道内装int类型的数据,并且管道大小能装10个数字,超过则阻塞
        pipe <- 10                 //向管道内放入数据
        pipe <- 9
        pipe <- 9
        pipe <- 7
        pipe <- 6
        var p1 int
        p1 = <-pipe //从管道取出数据
        fmt.Println(p1)
        fmt.Println(len(pipe))
      }
    • 2.4. 多返回值

      go的函数可以有多个返回值

      “`
      func main() {
      x,y:=p_fun(10,80)
      // x,_ := p_fun(10,80) 多返回值函数时,只要一个返回值
      fmt.Println(x,y)
      }

      //多返回值函数
      func p_fun(a int,b int) (int,int) { //函数传入2个整型参数,返回2个值,都为int类型
      sum := a+b
      avg := (a+b)/2
      return sum,avg
      }

    • 2.5. go的“包”的概念

      • 1.和python一样,把相同功能的代码放到一个目录,称之为包
      • 2.包可以被其他包引用
      • 3.main包是用来生成可执行文件,每个程序只有一个main包
      • 4.包的主要用途是提高代码的可复用性
      • 5.包的引用

      go在首行使用“package <包名>”来声明自己所在的包(主程序包为main包,也可以自定义包名),“import”引入其他的包,go自带的系统包所在的路径已经在“GOROOT”环境变量中设置好了
      可以使用“import”直接引入,而自己定义的包: package <包名> 在import导入时则需要相对路径:第三方包默认在“GOROOT”和“GOPATH”环境变量所在的路径下的src目录下寻找


      Go的package不支持使用“../”方式的相对路径,都是从$GOPATH/src下一层一层找的

    • 2.6. go文件编码规范

      使用gofmt <go文件>使go文件内的代码更规范(缩进等格式更规范),使用gofmt -w <go文件>将原来的go文件修改的更规范

    二、环境搭建

    环境搭建参考网址:https://blog.csdn.net/fearless11/article/details/70543932

    (1)开发环境搭建

    • 1.1 安装Go环境

      • 打开网址https://golang.org/dl/
      • 根据操作系统选择对应的安装包
      • 点击安装包进行安装(linux直接解压)
      • 设置环境变量(linux)

        1. export GOROOT=$PATH:/path/to/go/ #go的家目录

        2. export PATH=PATH:GOROOT/bin/ #go执行命令路径

        3. export GOPATH=/home/user/project/go #项目路径

      • 设置环境变量(window)

      参考:https://blog.csdn.net/fearless11/article/details/70543932

    • 1.2 开发环境搭建(IDE为VScode)

      • 打开网址:https://code.visualstudio.com/
      • 根据操作系统选择对应的安装包
      • 根据操作系统选择对应的安装包
      • 根据操作系统选择对应的安装包
      • 调试工具delve安装

        1. mac: brew install go-delve/delve/delve

        2. linux&windows: go get -u github.com/derekparker/delve/cmd/dlv #请确保已经安装了git

          1. 其他安装方式参考网址:https://github.com/derekparker/delve/tree/master/Documentation/installation
      • 注意事项: VScode开发的项目路径与环境变量 ==“GOPATH”== 的路径要一致,如 $GOPATH = d:\go_build 那么VScode开发的项目也要在d:\go_build目录下
    • 1.3 开发环境搭建(IDE为pycharm)

      '''新版本的pycharm可能已经无法使用'''
      
      pycharm的go语言开发支持插件下载:
      
      1.在pycharm中通过在线搜索go插件来安装
      
      2.可能因为版本原因,pycharm的在线插件安装可能搜索不到,可以采用本地安装的方法:
      
      插件本地安装包下载页面:
      
      https://plugins.jetbrains.com/plugin/5047-go-language-golang-org-support-plugin (pycharm社区版)
      https://plugins.jetbrains.com/plugin/9568-go (pycharm专业版)
      
      根据pycharm的idea版本号(idea版本号在安装目录下的“build.txt/readme.txt”文件中,通常是AA.BBBB.CC的形式)来选择下载插件的版本
      
      > 需要注意的是,pycharm的idea号AA.BBBB.CC 只要 AA与网站上的idea号对应上即可,它是一个范围,如idea号172.4343.24就可以下载范围“172.3968-172.*”对应的插件版本

    (2)编译环境和编译流程

    • 2.1 编译需要的目录环境

      我们的go项目的开发根目录由 GOPATH 环境变量决定了(范例为:d:/go_build),当我们需要开发项目工程时,需要在根目录下先创建src目录(规定死了),
      然后在 src 目录下创建开发的项目名称,如项目名称为app_store, 那么你的go文件应该在 d:/go_build/src/app_store目录下进行开发

      当使用,go get github.com/golang/tools相关命令来安装go的开发插件时,默认下载到 GOPATH/src/==GOPATH/src/github.com/golang/tools/…,然后再将
      该目录下的go文件编译成可执行的二进制文件,放入 $GOPATH/bin 目录下,来使用

      go get <github等网址>....,即在指定网址下载go文件,到GOPATH/src/GOPATH/bin 目录下,之后可以在IDE开发中直接使用(如调试台)

    • 2.2 编译go文件为二进制可执行代码

      使用 go build <go文件所在目录>命令,来进行go文件编译

      例如: ==GOPATH==为 d:/go_build时,编译d:/go_build/src/app_store/app.go文件时,编译的命令为 : `go build app_store/app.go则会在当前目录生成app.exe执行文件(Windows)

      go build时,默认会从$GOPATH/src/ 目录下开始寻找目录,因此只需要相对地址即可

      编译go文件为可执行文件并将文件放到指定位置下

      go build -o %GOPATH%/bin/calcs.exe app_store/app.go
      //将go文件编译到GOPATH变量所在目录下的bin目录里面,名称为calcs,后缀为.exe
      

      添加参数 “- o <执行文件路径(含文件名)>” 即可指定编译的文件位置,需要加上文件名和后缀(Windows为.exe;linux可不要)



    go基础介绍相关代码:

    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        //   bingfa()
    
        // go pi_pie()
    
        //a := my_sum(10,20)
        //fmt.Println(a)
    
        x,y:=p_fun(10,80)
        // x,_ := p_fun(10,80) 多返回值函数时,只要一个返回值
        fmt.Println(x,y)
    
        time.Sleep(2 * time.Second) //主进程停留2秒,否则并发线程还没有开启并执行完就结束了
    }
    
    //go的高并发
    func bingfa() {
        for i := 0; i <= 100; i++ {
            go fmt.Println(i) //go关键字即表示开启一个线程(轻量级的线程goroute)
        }
    }
    
    //goroute线程之间使用管道进行数据通信
    func pi_pie() {
        pipe := make(chan int, 10) //make关键字创建一个管道(关键字chan),管道内装int类型的数据,并且管道大小能装10个数字,超过则阻塞
        pipe <- 10                 //向管道内放入数据
        pipe <- 9
        pipe <- 9
        pipe <- 7
        pipe <- 6
        var p1 int
        p1 = <-pipe //从管道取出数据
        fmt.Println(p1)
        fmt.Println(len(pipe))
    }
    
    //带返回值的函数
    func my_sum(a int,b int) int {  //函数传入2个参数,类型为整型,返回值也为整型
        sum := a+b
        return sum
    }
    
    //多返回值函数
    func p_fun(a int,b int) (int,int) { //函数传入2个整型参数,返回2个值,都为int类型
        sum := a+b
        avg := (a+b)/2
        return sum,avg
    }


    go开发部分插件无法安装解决方案:

    官方的安装文档是使用go get github.com/tools/godep,很可惜,因为“网络”问题会报一个找不到golang.org/x/tools/go/vcs的错误。

    然而https://github.com/golang/tools 是 golang.org/x/tools 的一个镜像,代码是一样的,所以我是如下安装的:

    • 1.执行命令go get github.com/golang/tools

    • 2.在GOPATH\src\github.com\golang目录下就有tools文件夹。

    • 3.在src下和github.com平级新建golang.org文件下,在此文件夹下建x文件夹,然后将tools文件夹都复制进去。

    • 4.然后再执行go get github.com/tools/godep

    此时godep安装在你的GOPATH\bin目录下。

    对其他类似 golang.org/x/tools/go/vcs 的错误的办法也管用

    展开全文
  • 为什么Go语言在中国格外的"火

    万次阅读 多人点赞 2019-07-19 08:47:22
    go语言推出有几年了,似乎不温不火。但是在中国范围内,确实被关注的一塌糊涂。这是2017年2月份TIOBE出的编程语言排名:在拉勾网上搜索go的职位,结果有119个(2017年2月14日搜索结果),似乎还没有那么火爆:但是在...

    go语言推出有几年了,似乎不温不火。但是在中国范围内,确实被关注的一塌糊涂。

    这是2017年2月份TIOBE出的编程语言排名:

    这里写图片描述

    在拉勾网上搜索go的职位,结果有119个(2017年2月14日搜索结果),似乎还没有那么火爆:

    这里写图片描述

    但是在中国,很多公司,很多程序员都在谈论go语言,也就是说在中国对于go的关注异常火爆。

    根据谷歌搜索的统计,如下图:
    The graph above shows the searches for “golang” by country on Google Trends.
    这里写图片描述

    外国人专门写了一篇文章,来分析为什么go在中国如此火:
    《Why is Golang popular in China?》
    http://herman.asia/why-is-go-popular-in-china

    下面是知乎的回复:
    作者:匿名用户
    链接:https://www.zhihu.com/question/30172794/answer/47122000
    来源:知乎
    著作权归作者所有,转载请联系作者获得授权。

    这个“火”字看你怎么理解了。
    Go在国内更火只是感觉上的。比如推文,以及谈论的相关话题较多而已(但能有nodejs多么?),本身中国人口数量就多,按这个衡量的办法去看的话,swift在国内也比在国外火;
    实际上Go在国外更火(这里的火是实际的使用情况),对比一下国内和国外使用Go的程度、数量,Go相关的技术大会举办的频率和数量就一目了然了。
    
    Go在国内真正上被全栈使用的就七牛一家,但国外除了docker,coreOS还有很多初创企业。
    国内比较有影响力的就一个beego框架,你看看国外的有多少。
    
    去github上搜一下active的Go的project数量,看看Go在国外是不是没人用?我反正在github的trending里面几乎每天都能看到Go的project。hacker news上面有关Go的“xxx writen in Go”的炒作文也不要太多。
    这个 dariubs/GoBooks · GitHub 是有人整理的Go相关的书籍,看看是不是国外的书籍比国内的少?8月份K&R中的K也要推出属于Go的圣经了。
    
    另外老有人喜欢说:Google喜欢关闭产品,这玩意儿迟早死掉。可惜golang是开源项目,关不掉的,CloudFlare那个crypto的patch(Gerrit Code Review)以后可能会进Go的标准库,Godep已经成为事实上的包管理标准,这些都是社区自己搞出来的,和google一毛线关系没有。另外就是最近google自己一些主力产品或者平台在优先支持语言上,Go总是和java,c/c++,python一起名列其中,grpc就是一个例子等等。所以,觉得Go只是google的一个玩具的人,你的观点能不能站得住脚,自己掂量吧。
    
    我的个人观点是:
    Go显示已经站住了脚跟(如果是2013年,我还是不敢说这种话的),找到了属于自己的空间,但是比起那些主流的甚至nodeJS来说,还是使用的不够广泛。这个语言人为炒作也罢,一些人认为的google光环也罢,实际使用也罢,总之:
    这个语言已经站住脚跟了,能用于并且已经用于生产环境了,接下来几年只会一直呈上升势头。
    

    个人观点:

    1 一些真正使用go语言的公司:
    这些公司在高速发展的同时,Golang也因此在国内逐渐传播开来。在云计算时代,从国内Go 语言发展和应用来看,七牛算是国内第一家选 Go 语言做服务端的公司。早在2011年,当Go语法还没完全稳定下来的情况下,七牛就已经选择将Go作为存储服务端的主题语言。关于这点,七牛CEO许式伟谈到:编程哲学的重塑是 Go 语言独树一帜的根本原因,其它语言仍难以摆脱 OOP 或函数式编程的烙印,只有 Go 完全放弃了这些,对编程范式重新思考,对热门的面向对象编程提供极度简约但却完备的支持。Go 是互联网时代的C语言,不仅会制霸云计算,10 年内将会制霸整个 IT 领域。

    2 在中国程序员眼中,谷歌出品必属精品
    确实,在互联网世界,在开源世界,Google为我们贡献了太多太多。

    3 创业公司假装高逼格,假装geek范儿
    The word geek is a slang term originally used to describe eccentric or non-mainstream people; in current use, the word typically connotes an expert or enthusiast or a person obsessed with a hobby or intellectual pursuit, with a general pejorative meaning of a “peculiar person, especially one who is perceived to be overly intellectual, unfashionable, or socially awkward”.

    4 docker异常火爆,带动了对go语言的关注
    Docker是PaaS供应商dotCloud开源的一个基于LXC 的高级容器引擎,源代码托管在 GitHub 上, 基于Go语言开发并遵从Apache 2.0协议开源。

    5 go语言本身的一些特性
    部署简单
    并发性好
    性能好
    。。。

    6《go语言从入门到放弃》一书的火爆

    展开全文
  • Go语言编程入门

    万人学习 2018-10-22 21:38:04
    主要介绍Go语言相关的介绍和基础语法,学会开发环境的搭建和使用Go语言简单的编程。本视频教程适合Go语言初学者。
  • Go 语言为何不受待见?

    万次阅读 2019-03-25 17:48:40
    Go语言为何不受待见?事实上,Go仍然是一种相当不错的语言,并且逐渐取代Python成为很多人的首选语言。但是其却有一些问题,使得开发速度大受影响。本文就跟随作者一起解读...
        

    640?wx_fmt=gif

    Go语言为何不受待见?事实上,Go仍然是一种相当不错的语言,并且逐渐取代Python成为很多人的首选语言。但是其却有一些问题,使得开发速度大受影响。本文就跟随作者一起解读下Go中那些“硬伤”设计。

    640?wx_fmt=jpeg

    作者 | Ben E. C. Boyter
    译者 | 苏本如

    责编 | 郭芮
    出品 | CSDN(ID:CSDNnews)

    以下为译文:

    Go作为一种编程语言来说是相当体面的,然而,我在公司Slack(译者注:一种团队协作工具)的编程频道上对它的抱怨却越来越多(猜到我是做啥了的吧?)。我想我还是把这些抱怨写下来放在这里,这样当人们问我到底抱怨什么时,我就可以给他们一个链接,让他们直接到这里来看。


    640?wx_fmt=png


    过去一年左右的时间我都一直在大量地使用Go语言来编程,写一些命令行应用程序、scc(https://github.com/boyter/scc/)、lc(https://github.com/boyter/lc/)和一些API等等。其中包括一个供客户端调用代码高亮插件(https://github.com/boyter/searchcode-server-highlighter)的大规模API,这个代码高亮插件很快将会在https://searchcode.com/网站中使用。


    我在这里的批评是专门针对Go编程语言的。然而,我对我使用的每种编程语言都有抱怨。这里我引用一下C++编程语言之父Bjarne Stroustrup说过的一句话:


    “世界上只有两种编程语言:一种是人们抱怨的语言,另一种是没人使用的语言。”——Bjarne Stroustrup



    640?wx_fmt=png

    缺乏函数式编程



    我不是一个函数式编程的狂热分子。Lisp语言让我首先想到的是语言障碍,

    这可能是我使用Go语言编程时最痛苦的地方。


    和大多数开发者不一样,我不想要泛型,我认为这只会给大多数Go项目增加不必要的复杂性。我想要的是一些可以应用于内置的Slice(切片)和Map类型之上的函数方法。Slice和Map这两种类型都可以容纳任何类型,而且是泛型的,这种在某种意义上很神奇。然而Go的泛型不使用接口的话,就无法实现自己,这样就损失了所有的安全性和性能。


    举个例子,考虑下面的需求。


    给定两个字符串片断,找出这两段字符串片断中都包含的相同的子字符串,并将其放入一个新的字符串片断中,以便我们稍后处理它。


    existsBoth := []string{}
    for _, first := range firstSlice {
        for _, second := range secondSlice {
            if first == second {
                existsBoth = append(existsBoth, proxy)
                break
            }
        }
    }


    上面的Go语言的解决方法很简单。但我们还有其他方法,如使用Map来解决这个问题,使用Map可以减少运行时间,但是如果我们的内存容量有限,或者我们没有很大的片断需要处理,那么额外的运行时间并不足以抵消它带来的复杂性。


    让我们将其与Java中使用Stream和函数编程来实现相同逻辑的代码比较一下。


    var existsBoth = firstList.stream()
                    .filter(x -> secondList.contains(x))
                    .collect(Collectors.toList());


    上面的代码确实将算法的复杂性隐藏起来,从代码上看清楚要实现的逻辑容易得多。


    与实现同样功能的Go代码相比,上面的代码的意图是显而易见的,真正的简洁之处是添加额外的过滤器也变得非常简单。而如果用Go语言实现像下面的示例一样添加额外的过滤器,我们就必须在已经嵌套的for循环中再添加两个if条件。


    var existsBoth = firstList.stream()
                    .filter(x -> secondList.contains(x))
                    .filter(x -> x.startsWith(needle))
                    .filter(x -> x.length() >= 5)
                    .collect(Collectors.toList());


    有一些使用Go Generate的项目可以为你做到上面所说的,但是如果没有好的IDE支持的话,将上面的循环提取到它自己的方法中会非常笨重,而且会带来更多的麻烦。



    640?wx_fmt=png

    通道(channel)/并行切片(Slice)处理



    Go的通道(channel)通常非常简洁。虽然它们存在一些问题会导致它永久阻塞,但它们并不打算提供安全的并发性,因为通过竞争检测机制可以很容易地摆脱这些问题。对于一个不知道有多少个值或何时结束的流,或者如果处理这些值的方法不受CPU的制约,那么通道是一个很好的选择。


    通道不太擅长的是处理那些预先知道大小并希望并行处理的切片(Slice)。


    并行处理在几乎所有其他语言中都很常见,通常发生在你有一个大的列表或切片,使用并行流、并行LINQ(语言集成查询)、Rayon(一种数据并行库)、多进程或其他一些语法,使用所有可用的CPU,对该列表/切片进行迭代处理时。你将它们应用到你的列表上,然后返回处理好的元素列表。如果你的列表有太多的元素,或者你正在使用的函数太复杂,使用一个多核系统应该也可以更快地完成。


    然而,在Go语言中,你需要怎么实现它并不明确。


    一种可能的解决方法是为切片中的每个元素生成一个goroutine。因为goroutine的开销很低,所以在某种程度上,这是一个有效的策略。


    toProcess := []int{1,2,3,4,5,6,7,8,9}
    var wg sync.WaitGroup

    for i, _ := range toProcess {
        wg.Add(1)
        go func(j int) {
            toProcess[j] = someSlowCalculation(toProcess[j])
            wg.Done()
        }(i)
    }

    wg.Wait()
    fmt.Println(toProcess)


    上面的代码会保持切片中元素的顺序,但是我们的例子并不要求实现这点。


    上面的问题首先是添加一个waitgroup,并且必须记住递增并调用它。这对开发人员开说是额外负担。如果弄错了,这个程序将不会产生正确的输出,可能是不确定的结果,也可能永远不会执行完成。另外,如果你的列表很长,你要为列表中每个单独的元素生成一个goroutine。正如我之前所说,这本身不是一个问题,因为Go语言能毫无问题地做到这一点。但问题是,每一个goroutine都要为使用CPU的时间片而竞争。因此这不是执行此任务的最有效方法。


    你可能想做的是为每个CPU生成一个goroutine,并让它们依次挑选处理它的列表。增加一个goroutine的开销很小,但是对于一个迭代次数很多的循环来说,这个开销并不算小。当我在为scc项目工作时,我遇到了这个问题,它在每个CPU的内核上创建了一个goroutine。如果要完全用Go语言的方式来解决这个问题,你就需要创建一个通道,然后循环你的每个切片元素,让你的函数从该通道读取,然后再从另一个通道读取。


    让我们看看代码。


    toProcess := []int{1,2,3,4,5,6,7,8,9}
    var input = make(chan intlen(toProcess))

    for i, _ := range toProcess {
        input <- i
    }
    close(input)

    var wg sync.WaitGroup
    for i := 0; i < runtime.NumCPU(); i++ {
        wg.Add(1)
        go func(input chan int, output []int) {
            for j := range input {
                toProcess[j] = someSlowCalculation(toProcess[j])
            }
            wg.Done()
        }(input, toProcess)
    }

    wg.Wait()
    fmt.Println(toProcess)


    上面的代码先是创建了一个通道,循环我们的切片并将每个值放入其中。接着,为每个CPU内核创建一个goroutine来处理输入的值,然后等待它全部完成。要消化的代码很多。


    这不是一个你应该怎么做的问题,因为如果你的切片非常大,你可能不想有一个具有相同长度的缓冲区的通道,所以你实际上应该创建另一个goroutine来循环切片,并将这些值放入通道。当处理完成后,它关闭通道。我已经删除了这个代码,因为它使代码变得更长,而且我已经基本上知道怎么做了。


    Java的做法和上面大致相同。


    var firstList = List.of(1,2,3,4,5,6,7,8,9);

    firstList = firstList.parallelStream()
            .map(this::someSlowCalculation)
            .collect(Collectors.toList());


    是的,Go语言的通道(channel)和Java中的流(stream)并不是一回事,通道更接近于Java中的队列(queue),但我们这里的目的不是1对1的对比。我们想要的是使用我们所有的CPU内核来处理一个切片/列表。


    当然,如果某个slowcaluation实际上是一个在网络上调用的方法,或者是其他一些需要大量CPU的方法,那么这就不是一个问题。在这种情况下,通道和goroutine都很出色。


    这一问题与缺乏函数式编程有关。如果Go语言在slice/map对象之上有函数方法,那么添加这个功能是可能的。这也很烦人,因为如果Go支持泛型的话,就会有人可以把上面谈到的写成一个函数库,就像Rust的Rayon一样,每个人都会受益。


    顺便说一句,我认为这一点阻碍了Go语言在数据科学领域的任何成功,因此,为什么Python仍然是那里的王者。而Go语言在数字操作中缺乏表现力和力量——以上就是原因。



    640?wx_fmt=png

    垃圾回收(GC)



    Go语言的垃圾回收机制非常可靠。每次Go语言版本更新,我都发现我的应用程序变得更快了,原因通常是因为GC的改进。将延迟的优先级置于所有其它要求之上,对于API和UI来说,是一个完全可以接受的选择。同样地它也适用于任何有网络呼叫的情况,这些呼叫也会成为瓶颈。


    关键是Go语言对UI功能的实现没有任何好处(据我所知没有合适的绑定),当你需要尽可能大的吞吐量时,这个选择确实会伤害你。我在处理scc项目时遇到了一个大问题,scc是一个命令行应用程序,对CPU的要求很高。这是个问题,我添加了一个逻辑来关闭内存回收机制,直到内存使用量达到阈值。但是,我不能禁用它,因为程序在某些情况下工作时很快就会耗尽内存。


    对GC缺乏控制有时令人沮丧。你学会了接受它,但有时你会说“嘿,这里的代码真的需要尽可能快的运行,所以如果能切换到高吞吐量模式一段时间,那就太好了。”


    我认为随着Go语言的1.12版本的发布,这一点变得越来越不可能了,在这个版本中,GC看起来再次得到了改进,但是仅仅关闭和打开GC并不是我想要的控制。有时间的话我会再次深入了解一下。



    640?wx_fmt=png

    错误处理



    我不是唯一一个对这点有抱怨的人,但我必须写出来。


    value, err := someFunc()
    if err != nil {
        // Do something here
    }

    err = someOtherFunc(value)
    if err != nil {
        // Do something here
    }


    上面的代码看起来相当乏味。Go语言甚至不强制你处理大家建议的错误。你可以显式忽略它(这是否算作处理它?),你甚至可以完全忽略它。例如,我可以像这样重写上面的内容:


    value, _ := someFunc()

    someOtherFunc(value)


    你很容易发现我省略了somefunc返回的内容,但是someotherfunc(value)同时也可以返回错误,而我却完全忽略了这个错误,对它不作任何处理。


    老实说,我不知道有这里有什么解决办法。不过我喜欢Rust言语的问号(?)操作符,它可以避免这个问题。另外V-Lang(https://vlang.io/)看起来也可能有一些有趣的解决方案。


    另一个想法是可选类型(Optional Type)和删除nil,但是这些在Go语言的2.0版本中是永远不会出现的,因为它会破坏向后兼容性。



    640?wx_fmt=png

    总结



    总的来讲,Go仍然是一种相当不错的语言。如果你要我要写一个API,或者一些需要快速进行大量磁盘/网络调用的应用,它仍然是我的第一选择。事实上,我正处在这样一个阶段:Go已经取代Python,成为我要完成的大量的一次性任务的首选语言。数据合并任务除外,因为缺乏函数式编程仍然是一件痛苦的事情,这使得开发速度大受影响。


    对诸如像字符串stringA == stringB和编译错误的比较,你会发现Go语言的切片用在这里非常合适。它不像我在上面用来比较的Java语言那样经常有出人意料的结果。


    Go的二进制文件的大小可以更小(一些编译开关和upx(可执行文件压缩工具)可以解决这个问题),我希望它在某些方面运行得更快一些,GOPATH不是很好,但也没有每个人所说的那么糟糕,默认的单元测试框架缺少很多功能,Mocking有点痛苦等等。


    Go仍然是我使用过的一种更有效的语言。我会继续使用它,尽管我希望https://vlang.io/ 最终能够发布并且解决我的许多投诉的问题。它可能Go 2.0版,可能是Nim,也可能是Rust。现在有很多很酷的新语言可以玩。我们的开发人员真的被宠坏了。

    原文:https://boyter.org/posts/my-personal-complaints-about-golang/

    本文为 CSDN 翻译,如需转载,请注明来源出处。


     热 文 推 荐 

     华为 5G 硬实力

     Java 开发者希望未来使用 Python 和 Go

    “边缘计算将吞掉云计算!”

    ☞ 18 岁少年盗取价值 90 万元的萌乃币, 交易所被迫关停!

    李笑来登顶 GitHub TOP 榜!币圈大佬要教程序员如何自学编程

    ☞ 马云:蚂蚁金服这样做区块链!

    女生适合做程序员吗?

    Google首页玩起小游戏,AI作曲让你变身巴赫

    曝光!月薪 5 万的程序员面试题:73% 人都做错,你敢试吗?

    System.out.println("点个在看吧!");
    console.log("点个在看吧!");
    print("点个在看吧!");
    printf("点个在看吧!\n");
    cout << "点个在看吧!" << endl;
    Console.WriteLine("点个在看吧!");
    Response.Write("点个在看吧!");
    alert("点个在看吧!")
    echo "点个在看吧!"

    640?wx_fmt=gif点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

    640?wx_fmt=png喜欢就点击“在看”吧!
    展开全文
  • 我为什么放弃Go语言

    万次阅读 多人点赞 2020-02-19 18:55:03
    我为什么放弃Go语言?有好几次,当我想起来的时候,总是会问自己:这个决定是正确的吗?是明智和理性的吗?其实我一直在认真思考这个问题。开门见山地说,我当初放弃Go语言,就是因为两个“不爽”:第一,对Go语言...
  • Go语言的9大优势和3大缺点

    万次阅读 多人点赞 2018-09-20 22:06:01
    Go的优势 原因 1:性能 Go 极其地快。其性能与 Java 或 C++相似。在我们的使用中,Go 一般比 Python 要快 30 倍。以下是 Go 与 Java 之间的基准比较: 原因 2:语言性能很重要 对很多应用来说,编程...
  • Go适合做什么?为何这么多人偏爱Go语言

    万次阅读 多人点赞 2018-12-15 22:10:42
    Go作为Google2009年推出的语言,其被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。 对于高性能分布式系统领域而言,Go 语言无疑比...哪些大公司在使用Go语言: 1、Goog...
  • Go语言新手入门浅谈

    千次阅读 2020-05-28 11:54:25
    由于工作中存在与Go语言相关的内容,因此最近花费部分时间对Go语言进行了解,从基础语法开始对Go语言开始学习。Go语言语法简单,类C语法的特性导致学习Go语言学习容易,能够极快上手,然而若是希望深入理解Go语言仍...
  • Go语言(golang)教程】A Tour of Go:#1 Hello World! 【Go语言(golang)教程】A Tour of Go:#2 安装离线练习器 【Go语言(golang)教程】A Tour of Go:#3 包 【Go语言(golang)教程】A Tour of
  • Go语言圣经(中文版)

    千次阅读 2020-04-06 22:59:46
    http://golang-china.github.io/gopl-zh/index.html
  • golang: Go语言:简介

    千次阅读 2019-07-05 10:07:27
    go在win7/cmd64中的安装 golang: Go语言:简介(二) golang: Go语言:简介(一) golang: Go语言:简介 http://www.kuaizh.com/cntlist.php
  • 2017年我们公司需要快速迭代一款产品,当时,我们团队的后端框架是spring mvc ,该框架结构清晰,上手...在这种情况下,我们希望寻找一种新的框架或编程语言,我们期望他具备调试简单,上手快,启动速度快,保密性高,以...
  • 分享几本学习golang语言的书

    千次阅读 2018-11-29 15:24:00
    第一本是《goweb编程》-为什么先推荐这本呢...第二本是《go语言编程》--是七牛云存储许式伟写的,七牛是国内一个99%的程序都是用GO开发的公司对于golang有深入的了解和实践--为什么是第二本--因为里边讲解的东西需要...
  • go语言就业指南

    万人学习 2018-10-22 21:38:09
    授人予鱼不如授人予渔,本课程不但包含go语言从业者所的技能,而且还包含开发人员在开发中的学习技巧。掌握这些技巧和技能可以让你在面试中游刃有余。学习过程中任何问题联系: 4223665
  • Go语言完整的学习路线图

    万次阅读 2018-12-03 11:46:14
    Go语言完整的学习路线图 作为Go语言的学习爱好者,可以结合这张路线图看看Go 入门指南 Github 上《The Way to Go》中文译本的镜像 也可以下载:PDF、MOBI、EPUB https://github.com/Unknwon/the-way-to-go_ZH_CN ...
  • 一.所需安装包(windows)1....环境变量自动配置2.idea自行下载,激活二.idea集成go语言插件1.打开idea设置,以此点击file &gt;&gt; setting &gt;&gt; Plugins,如下图再点击Browse respositori...
  • raft协议的go语言实现

    千次阅读 2017-11-15 21:17:38
    raft协议的go语言实现  https://github.com/goraft/raft
  • golang的特性和优势

    千次阅读 2018-08-23 10:44:49
    go是21世纪的C语言,也是云计算时代的C语言,它的诞生是为了有更高的开发效率,它于2009年9月加入开源语言的大家庭,2012年正式发布。   go的最大优势就是执行速度和开发效率都很出色,而且从语言级别上支持并发...
1 2 3 4 5 ... 20
收藏数 236,628
精华内容 94,651
关键字:

go语言