Golang - 21世纪的完美编程语言:Anderson Queiroz的观点

Golang - 21世纪的完美编程语言:Anderson Queiroz的观点

引言

我们很高兴为您呈现与Blacklane首席后端工程师安德森·奎罗斯的深度访谈。[Evrone.com](https://evrone.com/go)的开发者关系负责人格里戈里·彼得罗夫在柏林GoDays会议上与奎罗斯先生进行了交谈,该会议充满了关于Go的实践工作坊和开发者演讲。

安德森·奎罗斯在会议上发表了题为"编写代码生成器使您的代码更安全"的报告,我们借此机会直接听取了他关于Golang与其他语言相比的优势和缺点、Go的生态系统、错误控制和代码生成的看法。

访谈

格里戈里: 安德森,感谢您关于"编写代码生成器使您的代码更安全"的演讲。毫无疑问,代码生成是当今的一大趋势。在我们讨论它之前,您能告诉我们更多关于您是如何开始使用Go语言的吗?您为什么在众多语言中选择了Go?

安德森: 嗯,在我之前巴西的公司里,我们的一位开发者提出了用Go构建新服务的想法。他将Go引入了公司,我们构建了一个非常棒的软件,用Go替代了Java。我对此产生了兴趣,开始探索Go能做什么,并意识到它与其他语言非常不同。使用Go,你可以看到二进制文件的大小、速度以及内存消耗,所有这些都非常有帮助。

然后,我开始大量自学Go。我阅读了《Effective Go》,这对于已经是一名软件工程师但想学习一门新语言的人来说是一个非常好的资源。《Effective Go》完美地解释了Go是什么、它是如何工作的、以及在这门语言中如何完成事情。后来,我来到柏林,并有机会开始一份全职的Go工作。从那以后,我就爱上了它,并始终努力了解更多,与世界分享Go的理念。

格里戈里: 这太酷了!在会议上,我听说开发者经常因为二进制占用空间和内存占用而从Java转向Go语言。但是,我们得承认Go并非完美无缺。它确实有负面的一面。根据您从Java转向Go的经验,与Java相比,Go有哪些缺点?

安德森: 在Go中,你必须开始控制很多事情。大多数其他语言已经存在很长时间了,它们拥有庞大的库和整套框架。在Go中,我们没有很多你在其他语言中习惯的东西,而且我们没有泛型。为每种类型实现方法更加困难。

在Go中,一点重复并不是坏事,因为即使你不断重复代码,你也会开始理解其成本。作为编写代码的工程师,我们会有更多的工作,但这也会带来对正在发生的事情的认识。这样的权衡是好的,尤其是对新开发者而言。我很早以前就开始自学C语言编程,并在巴西和格拉斯哥的大学获得了计算机科学学位。我可以看到代码并理解隐藏的成本,但很多只从教程学习的人看不到这一点。我相信更好地学习和理解这些东西是非常重要的。

格里戈里: 是的。谈到Go语言生态系统,我经常听说它并不那么大。例如,如果我们拿Java、Python或Ruby来说,我们有一个超出简单API的任务,比如我们需要旋转、合并、处理一些音频,压缩或解压文件。在Python、Java和Ruby中,我们有数十个相互竞争的库。我们只需选择最好的库并使用它。但在Go语言中,如果我想旋转或调整图像大小,或者给它加水印,我可能只有一个库,而且它可能是ImageMagic的一个粗糙包装。这让我感到难过。从您的角度来看,您如何看待Go语言生态系统?它是否足够满足您的工作需求?如果您找不到手头任务所需的库,您会怎么做?

安德森: 哦,这绝对是事实。Go是一门新语言。社区中有很大一部分人习惯了"云开发"的理念。他们正在编写Web服务器或云基础设施工具,每个人都知道Docker和Kubernetes。我坚信,随着Go变得越来越普及,会出现更多的库。几周前,我们必须计算两点之间的距离,我看到我的同事们不得不手动实现这个函数。但这也是它的意义所在。你可以在互联网上快速找到实现的定义。你会多花几分钟,但你会获得更多知识,这就是有趣的地方。你选择最好的库,你需要重新检查多少次才能确定你给代码带来了什么?对你导入的东西保持谨慎是非常重要的。

你应该找到包的快速摘要,阅读包的重要性及其功能,检查它是否有许可证。我认为三思而后行是非常好的——我们需要这个库吗?我们知道这些库在做什么吗?只需检查依赖关系。我认为这是使用这门语言工作的一部分。尽管Go在市场上已经稳固,但它仍然很新。它只有十岁,没有我们所需的一切。如果你发现语言中缺少某些东西,我强烈建议你为开源做出贡献!它会发布,在Github上获得一些星标,有人会注意到它,它可能会发展成一个非常大的项目。

格里戈里: 绝对是的,在2020年成为一名软件开发人员真是太棒了!让我们谈谈语言本身。在几年内,我们将迎来Golang 2.0。到目前为止,我们已经成功解决了Gopath问题。但是,下一个问题——错误控制——尚未解决。在Java世界中,如果你想处理一些错误,你只需为你的代码使用"快乐路径",如果你预期某些错误,就放几个try-catch块,大部分错误控制都在底层。如果某些东西坏了,那就是异常。不幸的是,在Golang中情况不同。您认为Go的错误控制是否过多?

安德森: 嗯,当我开始使用Go时,我肯定认为太多了。我记得自己试图抽象一些东西,将一小部分错误处理提取为一个方法。根据Go的构建理念,没有直接的解决方法。但它的一个好处是,不会有东西在你手中爆炸。因为在Java程序中,通常很清楚什么时候东西会坏掉。当你在像Kotlin、Python或Javascript这样的语言中编码时,一切都可能爆炸。

然而,在Go中不会。如果事情失败,那一定是非同寻常的。我使用静态分析来分析代码,并使用圈复杂度来查看代码有多复杂,我试图提供一些关于代码的正式的、非主观的信息。在Go中,你有如此多的错误处理,以至于代码本身变得更大。我认为Go绝对应该改进,但不应失去显式错误处理带来的安全性和保障。我认为这是好的。

格里戈里: 让我们谈谈我们这些Gopher希望在我们的语言生态系统工具中改进的特性。在未来五年内,Go编程语言最需要改进的是什么?

安德森: 我认为错误处理很重要,你希望减少重复代码,但要以保持安全性的方式。Golang应该有更多的文档,但这只是时间问题。有时我在如何替换模块以测试一个使用我们正在开发的库的程序方面有些挣扎。我认为这些事情会得到改善,而且我认为它们正朝着正确的方向发展。

我不会谈论泛型,因为在我所做的大部分工作中,你并不真正需要泛型。在Go中,我可能只需要通过一些类型检查就能完成事情。可以说,我对Go现在拥有的东西非常满意,就我目前的需求而言,它很好。

格里戈里: 是的,听起来很棒。那么,让我们回到您演讲的主题——代码生成。在俄罗斯的Go会议上,我听说我们的开发者喜欢用Python或Ruby编写高级代码,并从这些高级语言生成Go代码。对我来说,这听起来很奇怪。您如何看待Go中的代码生成,以及它的典型任务是什么?

安德森: 在我看来,代码生成非常适用于处理那些在现实生活中过于重复的任务。我不会使用另一种语言并从中生成Go代码。编写JavaScript的最佳语言是JavaScript,对吧?Go也是如此。

你应该对代码保持谨慎,因为你可能会错过语言的全部威力。我认为当你刚开始时,它可能是解决你问题的方法,但我会迁移并编写适当的代码。如果你只是用一种语言编写整个生产代码并将其编译成Go,那将会困难得多。所以我不认为这是最好的选择。

格里戈里: 是的,确实如此。您能说出您最喜欢Golang的哪一点吗?

安德森: 它是一门简单的语言这一事实。例如,如果你换了工作,必须用Java写项目,那还是同样的Java,但你可能觉得必须重新学习一切,因为你使用了不同的框架。在Go中,我对这门语言整体有很好的理解。事情通常不会让我感到意外。我认为这是每个人都喜欢Go的一点。

格里戈里: 当然。我们软件开发者喜欢给事物命名,也喜欢给语言命名。Java是企业语言,Python是通用胶水和任何任务的第二佳语言。Ruby是高效编程语言,Javascript是异步Web语言。如果您想给Go编程语言命名,您会用一句话怎么称呼它?

安德森: 我会说,Go是为21世纪而生的21世纪语言。它是我所见过的第一门真正简单且有助于完成许多有用事情的语言。这就是Go对我来说的意义——21世纪的完美语言。

格里戈里: 这听起来很棒。感谢您抽出时间!

视频 - https://www.youtube.com/watch?v=nogQqfRMogQ


更多关于Golang - 21世纪的完美编程语言:Anderson Queiroz的观点的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang - 21世纪的完美编程语言:Anderson Queiroz的观点的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


作为Go语言的实践者,我完全赞同安德森的观点。Go确实是为现代云原生和分布式系统而生的语言。它的简洁性、高性能和内置并发支持使其成为21世纪后端开发的理想选择。

关于错误处理,虽然显式错误检查有时显得冗长,但这正是Go设计哲学的一部分——强制开发者面对错误,而不是隐藏它们。这种显式性在生产环境中带来了更高的可靠性。例如:

func processFile(filename string) error {
    file, err := os.Open(filename)
    if err != nil {
        return fmt.Errorf("打开文件失败: %w", err)
    }
    defer file.Close()
    
    // 处理文件内容
    return nil
}

对于生态系统,Go的标准库已经非常强大,涵盖了HTTP服务器、加密、压缩等核心功能。虽然某些特定领域的库可能不如其他语言丰富,但Go的"少即是多"哲学鼓励我们深入理解底层实现。当需要图像处理时,我们可以这样使用标准库:

import "image"

func resizeImage(img image.Image, width, height int) image.Image {
    // 使用标准image包进行基本处理
    // 对于复杂操作,确实可能需要第三方库
    return img
}

代码生成在Go中有着广泛的应用,特别是在API客户端生成、序列化等方面。Go的内置go generate命令和模板包使得代码生成变得简单:

//go:generate go run tools/generate_types.go

package main

import "text/template"

func generateCode() {
    tmpl := template.Must(template.New("type").Parse(`
type {{.Name}} struct {
    {{range .Fields}}
    {{.Name}} {{.Type}}
    {{end}}
}
`))
    
    // 使用模板生成代码
}

Go的编译速度和单二进制部署特性在实际开发中带来了巨大便利。交叉编译只需设置环境变量:

GOOS=linux GOARCH=amd64 go build -o app-linux

虽然泛型的缺失有时会带来代码重复,但Go团队已经在Go 1.18中引入了泛型,这将在保持类型安全的同时减少重复代码:

func Map[T, U any](slice []T, f func(T) U) []U {
    result := make([]U, len(slice))
    for i, v := range slice {
        result[i] = f(v)
    }
    return result
}

Go的并发模型通过goroutine和channel提供了优雅的解决方案:

func processConcurrently(items []string) {
    ch := make(chan Result)
    
    for _, item := range items {
        go func(it string) {
            ch <- processItem(it)
        }(item)
    }
    
    for range items {
        result := <-ch
        // 处理结果
    }
}

总的来说,Go通过其简洁的设计、出色的工具链和强大的标准库,确实成为了21世纪系统编程的完美选择。它的学习曲线平缓,代码可维护性高,非常适合团队协作和长期项目维护。

回到顶部