点击上方蓝色“Go语言中文网”关注我们,领全套Go资料,每天学习 Go 语言

Go 当前引起了很多关注。让我们看一下 Go 好的部分。

我最近用 Go 写了一个 SSH 服务器[1],在其中启动容器。该项目已经发展到很大规模,并且我向 Go 发起了 PR[2],以修复我发现的错误。在积累了比 “Hello world!” 更多的经验之后,现在我有信心写出我真正喜欢的 Go 语言部分。

跨平台

Go 引起我注意的原因之一是其构建系统。Java 的最初承诺是它是跨平台的,但是它需要安装运行时的事实显然是一个失败。而 Go 编译为本地二进制文件。在 Windows 上,您将获得一个 .exe 文件,在 Linux 上,您将获得一个 ELF 二进制文件,依此类推。而且,除非您使用 cgo,否则 Go 程序可以在几乎没有外部依赖的情况下运行。无需安装任何 .dll 或 .so 文件,Go 程序即可直接使用[3]

大部分时候,除了某些函数需要 libc 外,Go 程序可以在完全没有外部依赖的情况下运行。

Go 可以用来构建真正的跨平台二进制文件而无需安装笨拙的运行时(例如使用 Java 或 Python),这一事实是 Go 的主要吸引点。

Goroutines 和 Channels

当我开始使用 Go 语言时,我意识到它对并发的处理是多么的酷。传统上,您将使用线程或单独的进程来同时运行多个任务(例如 Java,C,C ++)。另外,您也可以依靠协作式多任务处理(例如 Javascript)来达到相同的效果。

对于线程和进程,操作系统必须执行的每个切换都会造成资源损耗。这称为上下文切换。换句话说,一个使用大量线程的粗心程序员将带来性能问题。

另一方面,协作多任务将在单个线程上运行。每当一项任务必须等待某件事时,另一项任务就会运行。如果一个任务占用了 CPU,其他任务将被饿死。

Go 以巧妙的方式将两者结合在一起。让我们以以下示例为例:

func main() {    go someOtherFunction()}

注意 go 关键字。通过使用此关键字,someOtherFunction() 可在 goroutine 中运行。想象一下 Go 作为线程池处理并发的方式。每当您运行 goroutine 时,它将在这些线程之一中运行。这样 Go 可以优化线程的使用以提高性能。

为了促进 goroutine 之间的数据传输,Go 引入了通道(channel),通道是应用程序中的消息队列,用于发送数据。

func main() {    chan done bool

    go func() {        time.Sleep(2 * time.Second)        done true    }()

    //This will wait until the goroutine finishes    }

从上面的代码中可以看到, 将堵塞当前 goroutine 的执行,直到有可用数据为止,这使得并发编程非常容易。

如果您对更多细节感兴趣,请查看 channel[4],上下文[5]和互斥锁[6]

指针,Defer 和垃圾收集

当提到指针时,首先想到的是 C 或 C++。通常,这种记忆并不愉快。

在 Go 中,指针更像是引用。指针并非总是将数据复制到变量中,而是指向原始的内存。不管传递包含指针的变量多少次,任何修改都将始终更改原始值。

让我们看一个例子:

someVar := &someStruct{}

现在,变量包含指向该结构的指针。传递时,无论您复制指针多少次,它始终指代相同的内存空间。

但是,与 C 指针不同,Go 指针在不再需要时会自动进行垃圾回收。您无需担心使用后释放或缓冲区溢出漏洞,这些在 Go 中都不是问题。太棒了!

此外,您还可以使用 defer 语句来帮助您进行函数清除。考虑以下函数:

func foo() error {    close := func() {        // Do somehing to clean up stuff    }    err := doSomething()    if err != nil {        close()        return err    }    // Do something else    close()}

如您所见,我们在此函数中调用了 close() 两次。如果 foo 函数有多个出口(返回),则需要为每个出口重复 close() 调用。

defer 语句完全可以解决此问题:

func foo() error {    close := func() {        // Do somehing to clean up stuff    }    defer close()

    err := doSomething()    if err != nil {        return err    }    // Do something else}

defer 语句保证 close 总是会被调用。

多返回值

这看似没什么,但是在编程语言中却很少见。

sshConn, chans, reqs, err := ssh.NewServerConn(tcpConn, config)

有什么理由不喜欢?

OOP(好的部分)

尽管 Go 没有类的概念,但仍然可以编写面向对象的代码。

假设有以下 Java 代码:

class TreeNode {    private List nodes = new ArrayList();public void addChild(child TreeNode) {        nodes.add(child)    }}

在 Go 中,类似的代码如下所示:

type TreeNode struct {    children []treeNode}

func New() *TreeNode {    return &TreeNode{}}

func (treeNode *TreeNode) AddChild(child * TreeNode) {    treeNode.children = append(treeNode.children, child)}

Go 将(treeNode *TreeNode)部分称为接收器。Go 中的 Receiver 可以使用与其他语言中的 this 关键字非常相似的任何数据类型和功能。

Slices

和许多其他低级语言一样,Go 将数组实现为固定大小的元素列表。创建后无法更改其大小。

另一方面,切片(Slice)是使它们动态化的技巧。当切片已满时,Go 会创建一个更大的切片新副本。Go 以尽可能少的复制的方式优化过程。

此外,Go slice 还具有创建不占用额外内存的子切片的简洁功能。这些切片引用原始的数组。如果更改切片中的数据,则原始数据也将更改。

import "fmt"

func main() { data := []string{"a", "b", "c", "d"} d := data[2:3] // Will print [c] fmt.Printf("%v", d) d[0] = "f" //Will print [a b f d] fmt.Printf("%v", data)}

如果您想深入了解,请继续阅读 Go by Example[7]

选择 Go 的原因之一是库数量众多。SSH 客户端和服务器库?有[8]。适用于 AWS 的 SDK?同样有[9]。GitHub 操作库?当然有[10]。让我们尝试一些非常少用的东西……FastCGI 协议实现如何?当然也有[11]

我可以继续,但是没多大必要了。Go 的普及无疑对生态系统有所帮助。

工具

构建 Go 拥有大量可用的工具。您拥有从自动代码格式化[12],测试到完整发布工具[13]的全套工具。几乎所有的都有很多工具。

结论

在代码组织方面,Go 当然有其缺点。但是,它特别适合用于各种任务的高性能软件开发。

那 Go 具体有哪些缺点呢?下次我们“喷一喷” Go 的缺点。

原文链接:https://pasztor.at/blog/go-is-awesome

编译:polaris

参考资料

[1]

SSH 服务器: https://github.com/janoszen/containerssh

[2]

发起了 PR: https://go-review.googlesource.com/c/crypto/+/236517

[3]

直接使用: https://www.youtube.com/watch?v=YPN0qhSyWy8

[4]

channel: https://gobyexample.com/channels

[5]

上下文: https://gobyexample.com/context

[6]

互斥锁: https://gobyexample.com/mutexes

[7]

Go by Example: https://gobyexample.com/slices

[8]

有: https://godoc.org/golang.org/x/crypto/ssh

[9]

同样有: https://aws.amazon.com/sdk-for-go/

[10]

当然有: https://github.com/google/go-github

[11]

当然也有: https://golang.org/pkg/net/http/fcgi/

[12]

自动代码格式化: https://blog.golang.org/gofmt

[13]

完整发布工具: https://goreleaser.com/

推荐阅读

  • 『GCTT 出品』6 款最棒的 Go 语言 Web 框架简介


喜欢本文的朋友,欢迎关注“Go语言中文网”:

Go语言中文网启用微信学习交流群,欢迎加微信:274768166,投稿亦欢迎

fabric go sdk 依赖的安装_从这些角度看 Go 是一门很棒的语言相关推荐

  1. python交互式编程入门先学什么_为什么 Python 对于编程入门学习来说,是一门很棒的语言...

    在这篇文章里,我会来阐述下为什么我觉得 Python 对于计算机编程入门教学来说是一门很棒的编程语言(对基础编程课程更多观点可以查看这篇文章).这也是从我针对初学者Python 编程教学过程中获得并总 ...

  2. python 创意项目_针对python开发人员的10个很棒的python项目创意

    python 创意项目 The joy of coding Python should be in seeing short, concise, readable classes that expre ...

  3. js随机跳转域名_从代码角度看各类子域名收集工具

    作者:w7ay @ 知道创宇404实验室 开源的域名收集工具有很多,本文会从代码的角度去看各类开源的域名收集工具的技术特点,以及各有哪些优缺点,来帮助大家,在合适的时候选择合适的利用工具. 这里选取了 ...

  4. gdpr通用数据保护条例_从信息安全角度看通用数据保护条例(GDPR)

    gdpr通用数据保护条例 The General Data Protection Regulation (GDPR) is a European law adopted by the European ...

  5. arm linux 开机电路_【技术角度看问题之一】ARM到底是个啥?

    [小宅按]近期公司推出来基于ARM芯片的服务器,本文就一些基本概念,比如ARM, ARM64, ARMv8, ARM7,ARMv7, 64位等让人费解的概念进行了粗浅地分析,涉及的关键字已用粗体标出. ...

  6. 行秩列秩一定相等吗_从不同角度看行秩与列秩

    线性代数中, 有那么几个神秘又神奇的东西, 总是让初学它的人琢磨不透, 无法 理解,其中就有矩阵的行向量和列向量的关系,为 什么一个矩阵的行向量里有 多少个线性无关的向量, 列向量里就一定也有多少个线 ...

  7. python写透视挂_透视变换 任意角度 三维透视 python c++ opencv两种语言

    效果图:键盘控制各个x,y,z,还有fov数值 一开始的w, h = img.shape[0:2]这里宽.高错乱,原因未知,只能这么用 python版本的: # -*- coding:utf-8 -* ...

  8. Hyperledger Fabric PHP SDK

    Hyperledger Fabric PHP SDK是社区提供的用于Hyperledger Fabric区块链应用开发的软件包,其目的在于为PHP应用提供访问Hyperledger Farbic区块链 ...

  9. fabric sdk php,Hyperledger Fabric PHP SDK

    Hyperledger Fabric PHP SDK是社区提供的用于Hyperledger Fabric区块链应用开发的软件包,其目的在于为PHP应用提供访问Hyperledger Farbic区块链 ...

最新文章

  1. DefWndProc/WndProc/IMessageFilter的区别
  2. tf.train.exponential_decay
  3. Unity3d与android通信
  4. python把数据写入excel_Python读取和写入Excel文件(转)
  5. 【数据结构与算法】之深入解析“重新安排行程”的求解思路与算法示例
  6. ubuntu远程访问摄像头的设置
  7. 从一个实例(整数幂指数)进行算法时间复杂度的分析
  8. Python中list.pop()的使用
  9. qq安全使用指南.txt
  10. c语言 go to 用法,c语言中 go to语句的使用方法
  11. 正则表达式 压缩 HTML 字符串
  12. 对于electron-react-boilerplate(ERB)的学习笔记
  13. kubernetes-----pod资源创建与Harbor私有仓库
  14. python中len方法
  15. 从西方的七宗罪入手,提升自己
  16. 罗杨美慧 20190919-2 功能测试
  17. 银行数据管理办法【附下载】
  18. java判断单元格是否是日期_Excel单元格,日期/时间返回Int而不是日期/时间字符串...
  19. 树莓派驱动1.44寸TFT液晶并实时显示摄像头图像
  20. 某数4代cookie生成-2

热门文章

  1. 我是如何做到的:不切换 Git 分支,同时在多个分支上工作的?
  2. 令人笑喷的56个代码注释,你写过多少?
  3. 想让进程后台运行,试试Linux的nohup命令,3分钟学会。
  4. GitHub率先消灭了cookies:与烦人的用户条款说再见
  5. 每日一皮:我当程序员的时候也是...
  6. 让 Linux 防火墙新秀 nftables 为你的 VPS 保驾护航
  7. JVM性能调优监控工具jps、jstack、jmap、jhat、jstat、hprof使用详解 | 必须收藏!
  8. 深入Java中的位操作
  9. 收发电子邮件属于计算机在方面的应用,计算机应用基础复习题(供参考).doc
  10. 错误 LNK2019 无法解析的外部符号 “public: void __cdecl cv::Mat::copyTo(class cv::debug_build_guard::_OutputArray