1. 介绍

Go 是由 Google 创建的通用编程语言,它在 10 年前被开源。

Go 最初被设计为“低级”系统编程语言。它现在被广泛应用于许多不同的系统和应用领域,包括 Web 编程。它目前是最广泛使用的语言之一。

Go 是一种强类型语言,适用于构建大规模系统。Go 支持垃圾回收,这使得它更容易被技能水平不同的开发人员使用,并有助于减少许多与内存相关的问题。Go 在语言层面内置支持并发编程。

可执行 Go 程序构建为单独的独立二进制文件,没有运行时(共享)库依赖项,使得其更容易在许多不同的平台上部署。任何依赖的 Go 库在构建时作为源代码导入,而不是作为预构建的共享库/二进制文件,减少了库冲突的可能性。

就语法而言,Go 是最简单的编程语言之一,也是最容易学习和使用的语言之一。

本书从 Go 程序的高层结构开始,即包。然后,在下一章“程序初始化和执行”中,描述了如何构建和执行 Go 程序。我们将简要介绍 go 命令和模块/工作区系统。

在 Go 编程语言中,包用于组织源代码,也是代码共享的基本单元。在标准 go 工具链中,一个或多个包可以被分组到一个模块中,例如用于依赖管理和版本控制等,一个或多个模块可以使用工作区一起管理。

Go 程序是使用 Unicode 编写的。Go 编译器扫描输入程序中的字符,首先将它们转换为“tokens”序列,然后将其解析为可以最终转换为机器代码的内部数据结构。

在“词法元素”章节中,我们将讨论程序代码的各种低级方面。特别是,我们将讨论基本元素或令牌,如名称/标识符、关键字、注释、运算符和内置类型文字。许多编程语言都有类似的词法结构,如果您有 C 风格语言的经验,可以跳过本章。

Go 程序中的每个名称必须在使用前声明。这包括常量、变量、类型、函数、方法和导入的包的名称。我们在下一章中介绍声明的一般概念,并在接下来的六章中逐个讨论。

常量声明通过将名称与常量表达式绑定来创建常量。Go 支持布尔常量、数字常量和字符串常量。

变量用于在程序执行期间保存值。变量声明将名称与表达式和类型绑定,并为命名变量保留存储空间。我们还将介绍许多分配内存和初始化变量的方法。例如,可以使用内置的 new 和 make 函数来实现这一目的。

在现代编程语言中,类型起着至关重要的作用。Go 语言也不例外。在下一章“类型”中,我们将讨论 Go 的类型系统。

  • Go 包括一组内置或原始类型,这些类型在大多数编程语言中都可以找到。

  • Go 支持创建复合类型,如数组、切片、映射和通道。

  • struct 可用于创建结构化数据类型。

  • 类型声明允许从另一类型创建新类型或类型别名。Go 现在支持泛型类型声明。

  • Go 还支持指针类型,类似于 C/C++,但有一些限制。指针是变量的地址。

接口是一种特殊类型。非接口类型可以通过实现给定接口中声明的所有方法隐式地“实现接口”。用接口类型声明的变量可以在运行时用于实现此接口的任何类型。这提供了 Go 中的运行时多态。

自 Go 1.18 起,接口也可以用作泛型类型约束。在这种使用中,接口表示“类型集”而不是单个多态类型。Go 的泛型需要所有泛型类型参数的类型约束。当可以使用任何类型时,可以使用接口类型 any,它是 interface{} 的别名。

与任何 C 风格的编程语言一样,函数是 Go 中最重要的构造之一。(请注意,使用函数并不使 Go 成为函数式编程语言,这似乎是初学程序员之间的一个常见误解。)Go 的函数与 C 的函数相似,有一些小差别。特别是,Go 函数可以返回零个、一个或多个值。

Go 还支持方法声明语法。Go 中的方法只是一个定义在特定非接口类型(称为“接收器”)上的函数。这样,函数就可以根据它们的接收器的基础类型进行组织。Go 现在支持泛型函数。方法同样可以声明为泛型类型。

Go 还支持函数文字(或匿名函数),它们在语法上是表达式而不是声明。

表达式和语句是编程的基础。Go 支持大多数(如果不是全部)C 风格语言中的常见表达式。例如:

  • 常量表达式可用于声明和初始化常量变量。

  • 复合文字可用于创建复合类型(例如数组、切片和映射)的新值。

  • 索引和切片表达式可用于创建、更新或以其他方式操纵集合类型的变量。

  • 选择器表达式用于选择 struct 类型的字段和方法。

  • 函数和方法调用是表达式(无论它们是否返回任何值)。

  • 类型断言表达式用于运行时多态/接口类型的类型断言。

  • Go 中的通道接收操作(例如,<-channel)是一个表达式。

  • 常见的操作类型,包括算术、比较和逻辑操作等。

同样,Go 包括其他 C 风格编程语言中常见的语句。例如:

  • 赋值用于将值绑定到变量。

  • 许多表达式可以用作语句。这些被称为表达式语句。

  • 与 C 不同的是,后缀增加(++)和减少(--)操作在 Go 中是语句。

  • 信道发送操作,例如 channel<-,也是一个语句。

  • Go 支持 if、for 和 switch 语句,其语义与其他 C 风格语言基本相同。

  • Go 支持类似于 switch 的 select 语句来进行信道操作。

  • Go 包括常见的 continue、break 和 return 语句。

  • 由于 Go 的 switch 语句的工作方式,Go 还包括 fallthrough 语句。

  • Go 独特的 defer 语句可用于在函数返回之前“清理”。

  • go 语句用于创建新的 goroutine。Goroutines 用于 Go 中的并发编程,以及其他一些事情。

Go 为错误处理提供了最小的内置支持。按照惯例,函数返回错误值或 nil(表示非错误情况)作为最后一个返回值。Go 编程语言包括内置的 error 接口,通常用于错误返回类型。在“不可恢复”的错误情况下,Go 程序通常使用运行时恐慌。

Go 现在终于有了泛型类型系统。非常不幸的是,对于像 Go 这样的静态和强类型语言来说,这么重要的东西花了这么长时间才有。但是,尽管有这段历史,泛型并不是类型系统的临时添加。它是一个不可分割的部分。

如前所述,我们在类型定义和泛型函数的上下文中探讨泛型。但是,如果您是泛型的新手,此主题可能很令人生畏。因此,我们在最后一章中包括了一个奖金章节,详细阐述了泛型。特别是,我们为初学者提供了一个非正式的泛型介绍,然后提供了一个实现泛型栈数据类型的示例程序。此章节不是“语言参考”的一部分,可以跳过。

最后更新于