mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 06:19:44 +08:00
Merge pull request #230 from kigawas/master
Fix typo and polish some words
This commit is contained in:
@@ -36,7 +36,7 @@ Go 语言中另一个非常重要的特性就是它的构建速度(编译和
|
|||||||
|
|
||||||
依赖管理是现今软件开发的一个重要组成部分,但是 C 语言中“头文件”的概念却导致越来越多因为依赖关系而使得构建一个大型的项目需要长达几个小时的时间。人们越来越需要一门具有严格的、简洁的依赖关系分析系统从而能够快速编译的编程语言。这正是 Go 语言采用包模型的根本原因,这个模型通过严格的依赖关系检查机制来加快程序构建的速度,提供了非常好的可量测性。
|
依赖管理是现今软件开发的一个重要组成部分,但是 C 语言中“头文件”的概念却导致越来越多因为依赖关系而使得构建一个大型的项目需要长达几个小时的时间。人们越来越需要一门具有严格的、简洁的依赖关系分析系统从而能够快速编译的编程语言。这正是 Go 语言采用包模型的根本原因,这个模型通过严格的依赖关系检查机制来加快程序构建的速度,提供了非常好的可量测性。
|
||||||
|
|
||||||
整个 Go 语言标准库的编译时间一般都在 20 秒以内,其它的常规项目也只需要半秒钟的时间来完成编译工作。这种闪电般的编译速度甚至比编译 C 语言或者 Fortran 更加快,使得编译这一环节不再成为在软件开发中困扰开发人员的问题。在这之前,动态语言将快速编译作为自身的一大亮点,像 C++ 那样的静态语言一般都有非常漫长的编译和链接工作。而同样作为静态语言的 Go 语言,通过自身优良的构建机制,成功地了去除了这个弊端,使得程序的构建过程变得微不足道,拥有了像脚本语言和动态语言那样的高效开发的能力。
|
整个 Go 语言标准库的编译时间一般都在 20 秒以内,其它的常规项目也只需要半秒钟的时间来完成编译工作。这种闪电般的编译速度甚至比编译 C 语言或者 Fortran 更加快,使得编译这一环节不再成为在软件开发中困扰开发人员的问题。在这之前,动态语言将快速编译作为自身的一大亮点,像 C++ 那样的静态语言一般都有非常漫长的编译和链接工作。而同样作为静态语言的 Go 语言,通过自身优良的构建机制,成功地去除了这个弊端,使得程序的构建过程变得微不足道,拥有了像脚本语言和动态语言那样的高效开发的能力。
|
||||||
|
|
||||||
另外,Go 语言在执行速度方面也可以与 C/C++ 相提并论。
|
另外,Go 语言在执行速度方面也可以与 C/C++ 相提并论。
|
||||||
|
|
||||||
@@ -72,7 +72,7 @@ Go 语言从本质上(程序和结构方面)来实现并发编程。
|
|||||||
|
|
||||||
因为 Go 语言没有类和继承的概念,所以它和 Java 或 C++ 看起来并不相同。但是它通过接口(interface)的概念来实现多态性。Go 语言有一个清晰易懂的轻量级类型系统,在类型之间也没有层级之说。因此可以说这是一门混合型的语言。
|
因为 Go 语言没有类和继承的概念,所以它和 Java 或 C++ 看起来并不相同。但是它通过接口(interface)的概念来实现多态性。Go 语言有一个清晰易懂的轻量级类型系统,在类型之间也没有层级之说。因此可以说这是一门混合型的语言。
|
||||||
|
|
||||||
在传统的面向对象语言中,使用面向对象编程技术显得非常的臃肿,它们总是通过复杂的模式来构建庞大的类型层级,这违背了编程语言应该提升生产力的宗旨。
|
在传统的面向对象语言中,使用面向对象编程技术显得非常臃肿,它们总是通过复杂的模式来构建庞大的类型层级,这违背了编程语言应该提升生产力的宗旨。
|
||||||
|
|
||||||
函数是 Go 语言中的基本构件,它们的使用方法非常灵活。在第六章,我们会看到 Go 语言在函数式编程方面的基本概念。
|
函数是 Go 语言中的基本构件,它们的使用方法非常灵活。在第六章,我们会看到 Go 语言在函数式编程方面的基本概念。
|
||||||
|
|
||||||
|
@@ -12,15 +12,15 @@ Go 对于代码的缩进层级方面使用 tab 还是空格并没有强制规定
|
|||||||
|
|
||||||
实例:
|
实例:
|
||||||
|
|
||||||
gofmt -r “(a) -> a” –w *.go
|
gofmt -r '(a) -> a' –w *.go
|
||||||
|
|
||||||
上面的代码会将源文件中没有意义的括号去掉。
|
上面的代码会将源文件中没有意义的括号去掉。
|
||||||
|
|
||||||
gofmt -r “a[n:len(a)] -> a[n:]” –w *.go
|
gofmt -r 'a[n:len(a)] -> a[n:]' –w *.go
|
||||||
|
|
||||||
上面的代码会将源文件中多余的 `len(a)` 去掉。( **译者注:了解切片(slice)之后就明白这为什么是多余的了** )
|
上面的代码会将源文件中多余的 `len(a)` 去掉。( **译者注:了解切片(slice)之后就明白这为什么是多余的了** )
|
||||||
|
|
||||||
gofmt –r ‘A.Func1(a,b) -> A.Func2(b,a)’ –w *.go
|
gofmt –r 'A.Func1(a,b) -> A.Func2(b,a)' –w *.go
|
||||||
|
|
||||||
上面的代码会将源文件中符合条件的函数的参数调换位置。
|
上面的代码会将源文件中符合条件的函数的参数调换位置。
|
||||||
|
|
||||||
@@ -30,4 +30,4 @@ Go 对于代码的缩进层级方面使用 tab 还是空格并没有强制规定
|
|||||||
|
|
||||||
- [目录](directory.md)
|
- [目录](directory.md)
|
||||||
- 上一节:[构建并运行 Go 程序](03.4.md)
|
- 上一节:[构建并运行 Go 程序](03.4.md)
|
||||||
- 下一节:[生成代码文档](03.6.md)
|
- 下一节:[生成代码文档](03.6.md)
|
||||||
|
244
eBook/04.3.md
244
eBook/04.3.md
@@ -1,129 +1,129 @@
|
|||||||
# 4.3 常量
|
# 4.3 常量
|
||||||
|
|
||||||
常量使用关键字 const 定义,用于存储不会改变的数据。
|
常量使用关键字 `const` 定义,用于存储不会改变的数据。
|
||||||
|
|
||||||
存储在常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
|
存储在常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。
|
||||||
|
|
||||||
常量的定义格式:`const identifier [type] = value`,例如:
|
常量的定义格式:`const identifier [type] = value`,例如:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
const Pi = 3.14159
|
const Pi = 3.14159
|
||||||
```
|
```
|
||||||
|
|
||||||
在 Go 语言中,你可以省略类型说明符 `[type]`,因为编译器可以根据变量的值来推断其类型。
|
在 Go 语言中,你可以省略类型说明符 `[type]`,因为编译器可以根据变量的值来推断其类型。
|
||||||
|
|
||||||
- 显式类型定义: `const b string = "abc"`
|
- 显式类型定义: `const b string = "abc"`
|
||||||
- 隐式类型定义: `const b = "abc"`
|
- 隐式类型定义: `const b = "abc"`
|
||||||
|
|
||||||
一个没有指定类型的常量被使用时,会根据其使用环境而推断出它所需要具备的类型。换句话说,未定义类型的常量会在必要时刻根据上下文来获得相关类型。
|
一个没有指定类型的常量被使用时,会根据其使用环境而推断出它所需要具备的类型。换句话说,未定义类型的常量会在必要时刻根据上下文来获得相关类型。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
var n int
|
var n int
|
||||||
f(n + 5) // 无类型的数字型常量 “5” 它的类型在这里变成了 int
|
f(n + 5) // 无类型的数字型常量 “5” 它的类型在这里变成了 int
|
||||||
```
|
```
|
||||||
|
|
||||||
常量的值必须是能够在编译时就能够确定的;你可以在其赋值表达式中涉及计算过程,但是所有用于计算的值必须在编译期间就能获得。
|
常量的值必须是能够在编译时就能够确定的;你可以在其赋值表达式中涉及计算过程,但是所有用于计算的值必须在编译期间就能获得。
|
||||||
|
|
||||||
- 正确的做法:`const c1 = 2/3`
|
- 正确的做法:`const c1 = 2/3`
|
||||||
- 错误的做法:`const c2 = getNumber()` // 引发构建错误: `getNumber() used as value`
|
- 错误的做法:`const c2 = getNumber()` // 引发构建错误: `getNumber() used as value`
|
||||||
|
|
||||||
**因为在编译期间自定义函数均属于未知,因此无法用于常量的赋值,但内置函数可以使用,如:len()。**
|
**因为在编译期间自定义函数均属于未知,因此无法用于常量的赋值,但内置函数可以使用,如:len()。**
|
||||||
|
|
||||||
数字型的常量是没有大小和符号的,并且可以使用任何精度而不会导致溢出:
|
数字型的常量是没有大小和符号的,并且可以使用任何精度而不会导致溢出:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
const Ln2= 0.693147180559945309417232121458\
|
const Ln2= 0.693147180559945309417232121458\
|
||||||
176568075500134360255254120680009
|
176568075500134360255254120680009
|
||||||
const Log2E= 1/Ln2 // this is a precise reciprocal
|
const Log2E= 1/Ln2 // this is a precise reciprocal
|
||||||
const Billion = 1e9 // float constant
|
const Billion = 1e9 // float constant
|
||||||
const hardEight = (1 << 100) >> 97
|
const hardEight = (1 << 100) >> 97
|
||||||
```
|
```
|
||||||
|
|
||||||
根据上面的例子我们可以看到,反斜杠 `\` 可以在常量表达式中作为多行的连接符使用。
|
根据上面的例子我们可以看到,反斜杠 `\` 可以在常量表达式中作为多行的连接符使用。
|
||||||
|
|
||||||
与各种类型的数字型变量相比,你无需担心常量之间的类型转换问题,因为它们都是非常理想的数字。
|
与各种类型的数字型变量相比,你无需担心常量之间的类型转换问题,因为它们都是非常理想的数字。
|
||||||
|
|
||||||
不过需要注意的是,当常量赋值给一个精度过小的数字型变量时,可能会因为无法正确表达常量所代表的数值而导致溢出,这会在编译期间就引发错误。另外,常量也允许使用并行赋值的形式:
|
不过需要注意的是,当常量赋值给一个精度过小的数字型变量时,可能会因为无法正确表达常量所代表的数值而导致溢出,这会在编译期间就引发错误。另外,常量也允许使用并行赋值的形式:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
const beef, two, c = “meat”, 2, “veg”
|
const beef, two, c = "eat", 2, "veg"
|
||||||
const Monday, Tuesday, Wednesday, Thursday, Friday, Saturday = 1, 2, 3, 4, 5, 6
|
const Monday, Tuesday, Wednesday, Thursday, Friday, Saturday = 1, 2, 3, 4, 5, 6
|
||||||
const (
|
const (
|
||||||
Monday, Tuesday, Wednesday = 1, 2, 3
|
Monday, Tuesday, Wednesday = 1, 2, 3
|
||||||
Thursday, Friday, Saturday = 4, 5, 6
|
Thursday, Friday, Saturday = 4, 5, 6
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
常量还可以用作枚举:
|
常量还可以用作枚举:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
const (
|
const (
|
||||||
Unknown = 0
|
Unknown = 0
|
||||||
Female = 1
|
Female = 1
|
||||||
Male = 2
|
Male = 2
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
现在,数字 0、1 和 2 分别代表未知性别、女性和男性。这些枚举值可以用于测试某个变量或常量的实际值,比如使用 switch/case 结构 (第 5.3 节).
|
现在,数字 0、1 和 2 分别代表未知性别、女性和男性。这些枚举值可以用于测试某个变量或常量的实际值,比如使用 switch/case 结构 (第 5.3 节).
|
||||||
|
|
||||||
在这个例子中,`iota` 可以被用作枚举值:
|
在这个例子中,`iota` 可以被用作枚举值:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
const (
|
const (
|
||||||
a = iota
|
a = iota
|
||||||
b = iota
|
b = iota
|
||||||
c = iota
|
c = iota
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
第一个 `iota` 等于 0,每当 `iota` 在新的一行被使用时,它的值都会自动加 1;所以 `a=0, b=1, c=2` 可以简写为如下形式:
|
第一个 `iota` 等于 0,每当 `iota` 在新的一行被使用时,它的值都会自动加 1;所以 `a=0, b=1, c=2` 可以简写为如下形式:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
const (
|
const (
|
||||||
a = iota
|
a = iota
|
||||||
b
|
b
|
||||||
c
|
c
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
( **译者注:关于 iota 的使用涉及到非常复杂多样的情况,这里作者解释的并不清晰,因为很难对 iota 的用法进行直观的文字描述。如希望进一步了解,请观看视频教程 [《Go编程基础》](https://github.com/Unknwon/go-fundamental-programming) [第四课:常量与运算符](https://github.com/Unknwon/go-fundamental-programming/blob/master/lectures/lecture4.md)** )
|
( **译者注:关于 iota 的使用涉及到非常复杂多样的情况,这里作者解释的并不清晰,因为很难对 iota 的用法进行直观的文字描述。如希望进一步了解,请观看视频教程 [《Go编程基础》](https://github.com/Unknwon/go-fundamental-programming) [第四课:常量与运算符](https://github.com/Unknwon/go-fundamental-programming/blob/master/lectures/lecture4.md)** )
|
||||||
|
|
||||||
`iota` 也可以用在表达式中,如:`iota + 50`。在每遇到一个新的常量块或单个常量声明时, `iota` 都会重置为 0( **简单地讲,每遇到一次 const 关键字,iota 就重置为 0** )。
|
`iota` 也可以用在表达式中,如:`iota + 50`。在每遇到一个新的常量块或单个常量声明时, `iota` 都会重置为 0( **简单地讲,每遇到一次 const 关键字,iota 就重置为 0** )。
|
||||||
|
|
||||||
当然,常量之所以为常量就是恒定不变的量,因此我们无法在程序运行过程中修改它的值;如果你在代码中试图修改常量的值则会引发编译错误。
|
当然,常量之所以为常量就是恒定不变的量,因此我们无法在程序运行过程中修改它的值;如果你在代码中试图修改常量的值则会引发编译错误。
|
||||||
|
|
||||||
引用 `time` 包中的一段代码作为示例:一周中每天的名称。
|
引用 `time` 包中的一段代码作为示例:一周中每天的名称。
|
||||||
|
|
||||||
```go
|
```go
|
||||||
const (
|
const (
|
||||||
Sunday = iota
|
Sunday = iota
|
||||||
Monday
|
Monday
|
||||||
Tuesday
|
Tuesday
|
||||||
Wednesday
|
Wednesday
|
||||||
Thursday
|
Thursday
|
||||||
Friday
|
Friday
|
||||||
Saturday
|
Saturday
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
你也可以使用某个类型作为枚举常量的类型:
|
你也可以使用某个类型作为枚举常量的类型:
|
||||||
|
|
||||||
```go
|
```go
|
||||||
type Color int
|
type Color int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RED Color = iota // 0
|
RED Color = iota // 0
|
||||||
ORANGE // 1
|
ORANGE // 1
|
||||||
YELLOW // 2
|
YELLOW // 2
|
||||||
GREEN // ..
|
GREEN // ..
|
||||||
BLUE
|
BLUE
|
||||||
INDIGO
|
INDIGO
|
||||||
VIOLET // 6
|
VIOLET // 6
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
|
|
||||||
## 链接
|
## 链接
|
||||||
|
|
||||||
- [目录](directory.md)
|
- [目录](directory.md)
|
||||||
- 上一节:[Go 程序的基本结构和要素](04.2.md)
|
- 上一节:[Go 程序的基本结构和要素](04.2.md)
|
||||||
- 下一节:[变量](04.4.md)
|
- 下一节:[变量](04.4.md)
|
||||||
|
Reference in New Issue
Block a user