Go 语言入门

Go 语言是许多关键 Web 系统背后的驱动力,这使得学习 Go 语言成为程序员最好的投资之一。
921 位读者喜欢这个。
Getting started with Go

Ashley McNamara 和 Mat Ryer。 Go 地鼠由 Renee French 提供。CC BY-3.0

从 Reddit 到 Red Hat,Go 语言负责着 整个 Web 的关键系统。 Go 也是新兴一代语言的杰出成员。

“一个好的科幻小说应该能够预测的不是汽车,而是交通堵塞。”——弗雷德里克·波尔

Golang 着眼于表面现象之外,深入研究编程的次要影响。 交通堵塞在哪里? 可以避免吗? Go 表明,在很多情况下,答案是肯定的。

因此,学习 Go 是您作为程序员可以做出的最好的投资之一。 这可能是您第一次接触编译语言、简化的并发或静态类型。 这些都是极好的概念,几乎可以使任何语言的任何项目受益。

漫长的过去,但短暂的历史

在深入研究 Go 之前,让我们简要地绕道而行。 Go 的设计通常是优雅和实用的,但它的一些功能只有在一定的历史背景下才有意义。

这段历史始于 C。在很多方面,C 语言都是编程语言中的拉丁语。 它启发了 JavaScript、Ruby、Python、C++、C# 和 Java。 其中一些语言甚至是用 C 编写的。通过查看上述任何语言中的 if/else 和控制流语句,很容易发现 C 的影响。 C 最初是由 Dennis Ritchie 创造的,并用于构建 Unix。 从那里,C 进入了 Linux 的核心,C 一直是 Linux 的首选语言。

Go 是由来自 Unix 和 C 时代的 传奇人物创建的。 在 Google 工作期间,Robert Griesemer、Rob Pike 和 Ken Thompson 发现自己对 C 系列语言的常见陷阱感到沮丧。 正如 C++ 的创造者 Bjarne Stroustroup 所说:“C 语言很容易让你搬起石头砸自己的脚; C++ 使它变得更难,但当你这样做时,它会炸掉你整条腿。”

Go 成为 Robert、Rob 和 Ken 的解决方案。

Go 从 C 继承了很多优点。 关键字和语法具有精明的相似性,过程方法在两种语言中都处于最前沿。 另一方面,手动内存管理和长时间的编译是 C 中值得注意的难题。 Go 通过提供垃圾回收、内存安全和快速编译时间来规避这些问题。 对快速编译时间的关注直接导致了 Go 的另一个目标:生产力。

Java 是大型、面向企业的开发团队的首选语言。 Go 从 Java 这里获得灵感,并且还旨在成为大型企业开发团队的坚实基础。 另一方面,冗长和面向对象编程 (OOP) 继承是 Java 中值得注意的缺点。 Go 通过倾向于简洁的语法和接口而不是笨拙的 OOP 继承模型来避免这些缺陷。

也可以找到与动态语言的相似之处。 Go 具有强大的惯用风格,如 Python 的 PEP 8。 Go 倾向于约定优于配置,如 Ruby。 Go 将简单而直接的并发性融入到语言的核心中,如 Node.js 事件循环。 Go 在每种情况下的实现都不同,但相似之处仍然存在。

所有这些都说明,Go 最初是一种解决 C 语言一些长期存在的缺陷的方式。 它已经发展成为一种出色的通用编程语言。

Hello World

现在我们有了背景知识,我们准备学习 Go 了。 本指南假定您已经有一些编程背景。 如果这是您的第一次介绍,请查看 CodeAcademyLearn Code the Hard Way 上的 Python。 它们是为绝对初学者提供的更慢、更有条理的指南。

剩下的你呢? 我假设你有一些背景。 跟着我,是时候编写一些 Go 了。

步骤 1:访问 play.golang.org。 这是你看到的

 

the_go_playground-hello-world.png

步骤 2:单击运行按钮。

您刚刚在 Go 中运行了一个简单的 Hello World 程序。 简单! 让我们谈谈它,以便我们真正理解它。

第 1 行

package main

package main 行将启动我们的大部分 Go 程序。 这行只是告诉 Go 编译器我们想直接运行代码。 当我们准备编写自己的包时,我们将用我们包的名称替换 main 关键字。 简单。

第 3 行

import (
	"fmt"
)

当我们需要 Go 中的一个包时,我们 import 它。 如果我们习惯了 Python、Ruby 或 Node.js,这可能看起来很奇怪。 Go 的标准库被分解成一堆较小的包。 我们可以在 Golang 网站上找到完整列表。

在这种情况下,我们导入 fmt 包,它是 format 的缩写。 Gophers(即,Go 社区称呼 Go 程序员的方式)将 fmt 发音为“fumpt”。 现在我们已经运行了一些 Go 代码,我们就是 gophers。 导入允许我们使用 fmt 包。 我们将在下一个块中执行此操作。

第 7 行

func main() {
	fmt.Println("Hello, playground")
}

最后,我们正在运行代码。 每个 Go 程序都有一个 function main() 块,称为入口点。 如果我们是 C 程序员,这看起来很熟悉,如果我们是 Python、Ruby、Node.js 或类似的开发人员,则有点奇怪。 在动态语言中,执行从文档的顶部开始,并逐行向下滚动。 在 Go 中,它从入口点开始。

如果我们密切关注,我们可能还会猜测 func 关键字是一种定义函数的方式。 我们是对的。 (Go us!)

在入口点内,我们调用我们之前导入的 fmt 库,然后使用熟悉的点语法来调用一个方法。 在这种情况下,该方法是 Println。 正如我们可能猜到的那样,它会打印我们的“Hello”消息。

样式说明

最后,一些样式说明。 对你的变量和方法名使用 CamelCase。 也就是 FooBarfooBar 而不是 foo_bar。 Go 对打开大括号也有自己的看法。 看看如果你在 func main() 和第一个打开大括号 { 之间插入一个新行会发生什么。 在新行上运行带有大括号的代码应该会生成一个错误。

Go 中的间距也是标准化的。 尝试删除 fmt.Println 之前的制表符缩进,然后单击格式化按钮。 Go 的格式化工具应该始终通过替换制表符来修复缩进。

如果你像我一样,你可能会觉得使用全角制表符很奇怪。 这与我通常的编码风格大相径庭。 我编写的大部分 Ruby 和 JavaScript 代码都用两个空格代替制表符。 Go 在这里有自己的看法,但幸运的是,我可以继续写我那两空格的制表符。 只要它留在我的本地机器上,Go 就不介意。 当我提交到 GitHub 或公开访问的存储库时,我只需首先 运行 go fmt 来修复间距。

一个更好的选择是安装一个插件,如 EditorConfig。 这将使我的 Go 代码看起来像 Go 代码,而我的其他代码则保持我喜欢的任何风格。 作为一个奖励,EditorConfig 支持每个项目的设置,这对于通常因项目而异的语言来说是很好的,因为它们不支持规范风格(如 Python 或 Go)。

基础知识

到目前为止,我们已经编写了一些 Go 代码,这很棒。 如果我们想保持良好的状态,我们需要在我们的本地机器上 安装 Go

之后,是时候深入研究基础知识了。 我们仍然需要查看变量、控制结构(例如,if/else)、类型等等。 Go by Example 是一个很棒的资源。 官方 Go 导览是一个不错的选择。

Go by Example 的 变量部分 是开始这段新学习之旅的好地方。 从变量到 结构体部分 是我们 Go 学习下一阶段的一个不错的选择。

这里重要的是什么? 第一个收获是静态类型有多好。 在 Python、Ruby 和 JavaScript 中,大量的测试都用于类型检查。 此函数的输入是我们想要的类型吗? 如果不是,则测试该行为。 这种测试通常会变成很多代码。

相比之下,Golang 通过静态类型来拯救我们。 看一下 下面的例子

the_go_playground-static-types.png

var hi string = "Hello, playground" 

讲述了故事的一部分。 另一部分是在定义函数时讲述的

func foo(bar string) {
	fmt.Println(bar)
}

该函数明确了它将接受哪些类型。 尝试将 hi 从字符串更改为 int。 在下次运行时,我们将收到一条方便的错误消息。


main.go:14: cannot use hi (type int) as type string in argument to foo

快速的前期定义可以为我们节省大量的错误、测试和麻烦。

其他值得注意的? 如果我们导入一个我们不使用的包或声明一个我们不使用的变量,Go 会报错。 这只是一个让我们保持诚实的不错的功能。 尝试声明一个变量,看看当你运行没有相应 Println 的代码时会发生什么。

最后,指针。 如果它们是一个新概念,它们可能是一个很大的障碍。 指针也是 Go 最有价值的学习机会之一。 这里要注意的重点是 Go 按值传递

按值传递意味着,大多数情况下,Go 会在对变量采取操作之前创建一个副本。我说大多数情况,是因为我们可以通过使用指针来覆盖这种行为。这就是指针的,嗯,重点。 作为额外的好处,了解所有这些是更好地理解内存管理的好方法。

超越基础

我们甚至还没有接触到 Go 最好的部分! 我问我在 CoreOS(我们大量使用 Go 的地方)的同事,他们认为什么重要。 我收到了各种各样的答案,我没有足够的字数在这里详细介绍。(如果您有兴趣,channels,goroutines,组合和类型嵌入是众多建议中的一部分。)

相反,我将用我最后的几句话来表达我的经济观点。 首先,通过Go by Example和官方的Tour of Go继续学习。 如果您发现自己渴望更实质性的内容,Go in Action 是一本很棒的书。 避免使用Go Programming Language (GoPL),因为它是一本详尽的参考书。 这是一本很棒的书,但作为 Go 的新手,它可能会让你感到精疲力竭。

如果你想学游泳,你需要跳进水里。 换句话说,一个人只能通过阅读学到很多东西——在某个时候你需要应用它。 Go 的 pkg 文档是找到可以修改的示例的好地方。 考虑一下来自net/http 文档的 blob,它向您展示了如何设置一个简单的 Web 服务器。 其他很棒的资源包括exercism.ioProject Euler

最后,社区! Go 有 Slack、IRC 和许多其他频道,我们可以在其中寻求帮助或分享笑声。 我强烈建议加入。

结束语

Go 是一种很棒的语言。 它在短时间内取得了巨大的发展,成为许多著名项目的基石。

我希望您学习 Go 玩得开心。 并且,一定要告诉我进展如何!

User profile image.
Paul Burt 是 CoreOS 的社区经理。 他正在赞同您的 /r/kubernetes 帖子,并在 freeNode 上回答您的 #coreos 问题。 Paul 擅长简化基础设施,并使复杂的主题变得平易近人。 他喜欢自酿啤酒,阅读独立漫画,并在他的电脑不按他想要的方式工作时冲它大喊大叫。

6 条评论

很棒的介绍! 非常感谢分享。 :)

几年前我在大学里学习了 2 年的 Java 编程,这是我听过的最好的编码解释之一。 干得好,Paul!

写得很好! 我随意地开始并最终读完了整篇文章。 非常感谢。

一篇写得很好的文章。 我一直在寻找学习 GO 语言的起点,这就是它! 谢谢你。

Creative Commons License本作品采用 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.