From deef0f833f99f0bd2baca16ef4c6337388bab5c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Sun, 10 Sep 2023 21:45:19 +0800 Subject: [PATCH] =?UTF-8?q?post:=E5=9F=BA=E6=9C=AC=E5=AE=8C=E6=88=90?= =?UTF-8?q?=E6=A0=87=E8=AF=86=E7=AC=A6=E5=92=8C=E5=85=B3=E9=94=AE=E5=AD=97?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/SUMMARY.md | 3 +- src/grammar/identifier-keyword.md | 93 +++++++++++++++++++++++++++++++ src/grammar/index.md | 41 ++++++++++++++ 3 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 src/grammar/identifier-keyword.md create mode 100644 src/grammar/index.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 89ff07a..a869ac8 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -21,7 +21,8 @@ - [Go Module](./project-structure/module/index.md) - [go.mod 的组织](./project-structure/module/mod-file.md) - [依赖版本的发布](./project-structure/module/release.md) -- [Go 基本语法]() +- [Go 基本语法](./grammar/index.md) + - [标识符与关键字](./grammar/identifier-keyword.md) - [基本数据类型]() - [表达式]() - [语句]() diff --git a/src/grammar/identifier-keyword.md b/src/grammar/identifier-keyword.md new file mode 100644 index 0000000..401aa66 --- /dev/null +++ b/src/grammar/identifier-keyword.md @@ -0,0 +1,93 @@ +# 标识符和关键字 + +标识符和关键字在任何语言的程序中都是组成程序代码的基础元素,它们在程序代码中都有独特且专一的功能。 + +## 标识符 + +标识符在代码中主要用来命名程序实体,例如变量、类型等。在 Go 语言中,标识符是一个由一个或者多个字母或数字组成的序列,其第一个字符必须是字母,不能是数字。 + +标识符的语法定义为: + +``` +identifier = letter { letter | unicode_digit } . +``` + +在 Go 语言中,由一些标识符是在全局隐式定义的,它们已经具有了特殊含义的指代,不可被挪用于指代其他内容。以下表格中即是 Go 在全局定义的标识符。 + +| 标识符 | 类型 | 含义 | +| ------------ | ---- | -------------------------------------------------------- | +| `any` | 类型 | 指代任意类型 | +| `bool` | 类型 | 指代布尔类型 | +| `byte` | 类型 | 指代字节类型 | +| `comparable` | 类型 | 指代可比较类型 | +| `complex64` | 类型 | 指代 64 位复数类型 | +| `complex128` | 类型 | 指代 128 位复数类型 | +| `error` | 类型 | 指代描述错误的接口 | +| `float32` | 类型 | 指代 32 位单精度浮点类型 | +| `float64` | 类型 | 指代 64 位双精度浮点类型 | +| `int` | 类型 | 指代当前机器架构支持长度的整型 | +| `int8` | 类型 | 指代 8 位长度的单字节整型 | +| `int16` | 类型 | 指代 16 位长度的双字节整型 | +| `int32` | 类型 | 指代 32 位长度的四字节整型 | +| `int64` | 类型 | 指代 64 位长度的八字节整型 | +| `rune` | 类型 | 指代一个 UTF-8 码点字符 | +| `string` | 类型 | 指代字符串类型 | +| `uint` | 类型 | 指代当前机器架构支持长度的无符号整型 | +| `uint8` | 类型 | 指代 8 位长度的单字节无符号整型 | +| `uint16` | 类型 | 指代 16 位长度的双字节无符号整型 | +| `uint32` | 类型 | 指代 32 位长度的四字节无符号整型 | +| `uint64` | 类型 | 指代 64 位长度的八字节无符号整型 | +| `uintptr` | 类型 | 指代一个用于保存指针地址的整型 | +| `true` | 常量 | 指代真值 | +| `false` | 常量 | 指代假值 | +| `iota` | 常量 | 指代常量序列计数起始的`0` | +| `nil` | 零值 | 指代空指针 | +| `append` | 函数 | 用于向一个切片中增加元素 | +| `cap` | 函数 | 返回一个切片的容量(capacity) | +| `clear` | 函数 | 清空 map,重置切片中的全部元素(Go 1.21 以后可用) | +| `close` | 函数 | 用于关闭通道 | +| `complex` | 函数 | 用于构建一个复数类型 | +| `copy` | 函数 | 用于复制一个切片 | +| `delete` | 函数 | 用于删除 map 中的键值对和切片中的元素 | +| `imag` | 函数 | 获得一个复数的虚数部分 | +| `len` | 函数 | 计算字符串或者切片、数组等可被计数内容的长度(元素数量) | +| `make` | 函数 | 创建一个切片、Map、结构体的实例 | +| `max` | 函数 | 获取给定值中的最大值(Go 1.21 以后可用) | +| `min` | 函数 | 获取给定值中的最小值(Go 1.21 以后可用) | +| `new` | 函数 | 创建一个指定类型的实例并返回其引用 | +| `panic` | 函数 | 中断程序运行并抛出异常 | +| `println` | 函数 | 在控制台中输出指定内容 | +| `real` | 函数 | 获得一个复数的实数部分 | +| `recover` | 函数 | 捕获`panic`抛出的异常,并使程序从异常状态中恢复 | + +## 关键字 + +关键字实际上也是标识符,但是是语言中保留的内容,因为其在语言中具有专门的用途和意义,所以不能被用作普通的标识符。Go 中的关键字主要有以下这些。 + +| 关键字 | 功能 | +| ------------- | ---------------------------------------- | +| `break` | 用于退出循环 | +| `case` | 用于定义`switch`语句的分支条件 | +| `chan` | 用于标识通道类型 | +| `const` | 用于定义常量 | +| `continue` | 用于提前结束当前的循环,并开始下一次循环 | +| `default` | 用于定义`switch`和`select`中的默认分支 | +| `defer` | 用于定义延后执行的语句 | +| `else` | 用于定义`if`语句的分支 | +| `fallthrough` | 用于打通`switch`语句中的多个`case`分支 | +| `for` | 用于定义循环 | +| `func` | 用于定义函数 | +| `go` | 用于启动协程 | +| `goto` | 用于执行强制跳转 | +| `if` | 用于定义条件分支 | +| `import` | 用于引入其他的包 | +| `interface` | 用于定义接口 | +| `map` | 用于定义 map 类型 | +| `package` | 用于定义当前代码文件归属的包 | +| `range` | 用于定义范围边界 | +| `return` | 用于从函数中返回值 | +| `select` | 用于监听和响应通道 | +| `struct` | 用于定义结构体 | +| `switch` | 用于定义复杂分支结构 | +| `type` | 用于定义类型 | +| `var` | 用于定义变量 | diff --git a/src/grammar/index.md b/src/grammar/index.md new file mode 100644 index 0000000..99f8658 --- /dev/null +++ b/src/grammar/index.md @@ -0,0 +1,41 @@ +# Go 基本语法 + +任何一门编程语言都是由一些基本的词汇元素组成的,Go 语言也不例外。构成 Go 语言程序代码的基本元素,归类起来主要是标识符、关键字、操作符、标点符号和文字五类。其中所有的空白字符包括空格、Tab 制表符、回车等,都会在程序编译时被忽略,它们只是程序代码中基本元素的分隔符,而不是代码的基本元素之一。 + +## 分号 + +在在大多数语言中,分号都是用来作为一个语句结束的标记的,在 Go 语言中也不例外,但是 Go 提供了一些独特的解析规则使得我们在大部分情况下可以省略分号的书写。 + +1. 当一行的内容被分解为 Token 时,最后一个 Token 是以下内容的时候,分号会被自动插入。 + - 一个标识符; + - 一个整型、浮点型、复数类型、字符或者是字符串的字面量; + - `break`、`continue`、`fallthrough`或者是`return`中的一个; + - `++`、`--`、`)`、`]`或者是`}`中的一个。 +1. 一个在`)`或者`}`之前的独占一行的复杂语句。 + +基于这两条规则,绝大多数语句结尾的分号都可以被省略掉,读者可以在实际编程练习中仔细体会一下。 + +## 代码文档字符集 + +Go 语言的代码文档是采用 UTF-8 编码格式的,所以在代码文档中基本上可以使用任意合法的 UTF-8 字符。但是 Go 语言在其 EBNF 格式的定义中,还是将代码文档中可以使用的字符划分成了以下几类: + +- 换行符,在 EBNF 定义中使用`newline`标识。 +- UTF-8 字符,是指所有除了换行符以外的 UTF-8 码位,在 EBNF 定义中使用`unicode_char`标识。 +- UTF-8 字母,是指 UTF-8 码位中,所有被归类为字母的码位,在 EBNF 定义中使用`unicode_letter`标识。 +- UTF-8 数字,是指 UTF-8 码位中,所有被归类为数字或者数字位的码位,在 EBNF 定义中使用`unicode_digit`标识。 + +通过以上对于代码文档中可以使用的字符的定义,再结合 Go 语言代码中出现的内容,就可以定义出也以下基本字符和数字。 + +``` +letter = unicode_letter | "_" . +decimal_digit = "0" ... "9" . +binary_digit = "0" | "1" . +octal_digit = "0" ... "7" . +hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" . +``` + +这套定义也就是说,在 Go 语言代码中,所有的合法字母除了包括 UTF-8 中被归类为字母的码位以外,还包括下划线`_`。剩下的四个定义分别对应十进制数字、二进制数字、八进制数字和十六进制数字。 + +```admonish tip +这些基础的EBNF定义虽然简单,但是它是构成后文中其他复杂EBNF定义的基础。 +```