This commit is contained in:
Unknown
2013-04-16 17:03:20 -04:00
parent e1a179ce1e
commit 88c839dd42

View File

@@ -12,7 +12,6 @@ Example 4.1 [hello_world.go](examples/chapter_4/hello_world.go)
}
##4.2.1 包的概念、导入与可见性
包是结构化代码的一种方式:每个程序都由包(通常简称为 pkg的概念组成可以使用自身的包或者从其它包中导入内容。
如同其它一些编程语言中的类库或命名空间的概念,每个 Go 文件都属于且仅属于一个包。一个包可以由许多以 `.go` 为扩展名的源文件组成,因此文件名和包名一般来说都是不相同的。
@@ -106,10 +105,9 @@ Example 4.2 [alias.go](examples/chapter_4/alias.go)
你可以在使用 `import` 导入包之后定义或声明 0 个或多个常量const、变量var和类型type这些对象的作用域都是全局的在本包范围内所以可以被本包中所有的函数调用如 [gotemplate.go](examples/chapter_4/gotemplate.go) 源文件中的 c 和 v然后声明一个或多个函数func
##4.2.2 函数
这是定义一个函数最简单的格式:`func functionName()`
你可以在括号`()`中写入 0 个或多个函数的参数(使用`,`分离),每个参数的名称后面必须紧跟着该参数的类型。
你可以在括号 `()` 中写入 0 个或多个函数的参数(使用逗号 `,` 分隔),每个参数的名称后面必须紧跟着该参数的类型。
main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数( ***译者注:如果有 init() 函数则会先执行该函数*** )。如果你的 main 包的源代码没有包含 main 函数,则会引发构建错误 `undefined: main.main`。main 函数即没有参数,也没有返回类型(与 C 家族中的其它语言恰好相反)。如果你不小心为 main 函数添加了参数或者返回类型,将会引发构建错误:
@@ -193,7 +191,6 @@ Example 4.2 [hello_world2.go](examples/chapter_4/hello_world2.go)
godoc 工具(第 3.6 节)会收集这些注释并产生一个技术文档。
##4.2.4 类型
可以包含数据的变量(或常量)可以使用不同的数据类型或类型来保存数据。使用 var 声明的变量的值会自动初始化为该类型的零值。类型定义了某个变量的值的集合与可对其进行操作的集合。
类型可以是基本类型intfloatboolstring结构化的复合的structarrayslicemapchannel只描述类型的行为的insterface。
@@ -237,14 +234,14 @@ godoc 工具(第 3.6 节)会收集这些注释并产生一个技术文档。
每个值都必须在经过编译后属于某个类型(编译器必须能够推断出所有值的类型),因为 Go 语言是一种静态类型语言。
##4.2.5 Go 编程的一般结构
下面的程序可以被顺利编译但什么都做不了,不过这很好地展示了一个 Go 程序的首选结构。这种结构并没有被强制要求,编译器也不关心 main 函数在前还是变量的声明在前,但使用统一的结构能够在从上至下阅读 Go 代码时有更好的体验。
下面的程序可以编译,但并没有什么用处,但展示 Go 程序的首选结构。这种结构不是必须的编译器不关心main()或变量声明在最后,但一个标准的结构使代码从上到下有更好的可读性。
所有的结构将在这一章或接下来的章节中进一步地解释说明,但总体思路如下:
所有结构将在这接下来的章节进一步解释说,但总体思路是:
- import 之后: 定义常量,变量和类型
- 如果需要,然后是 init() 函数: 这是一个特殊的功能,每一个包可以包含并首先执行
- 然后 main() 函数(只在 package main 中)
- 然后是剩下的函数,首先是类型的方法,或是 main() 函数中先后顺序调用的函数;或方法和功能,按字母顺序的方法和函数排序很高的。
- 在完成包的 import 之后,开始对常量、变量和类型的定义或声明。
- 如果存在 init 函数的话,则对该函数进行定义(这是一个特殊的函数,每个含有该函数的包都会首先执行这个函数)。
- 如果当前包是 main 包,则定义 main 函数
- 然后定义其余的函数,首先是类型的方法,接着是按照 main 函数中先后调用的顺序来定义相关函数,如果有很多函数,则可以按照字母顺序来进行排序。
Example 4.4 [gotemplate.go](examples/chapter_4/gotemplate.go)
@@ -272,34 +269,33 @@ Example 4.4 [gotemplate.go](examples/chapter_4/gotemplate.go)
Go 程序的执行(程序启动)顺序如下:
1在 package main 中的包全部导入,按标明的顺序:
2如果导入包1被这个包调用递归但是一个确定的包只会被导入一次
3然后每一个包以相反的顺序中所有的常量和变量都被评估,如果包含这个函数,将执行 init() 方法。
4最后在 package main 中也一样,然后 main() 函数开始执行。
1. 按顺序导入所有被 main 包引用的其它包,然后在每个包中执行如下流程:
2. 如果该包又导入了其它的包,则从第一步开始递归执行,但是每个包只会被导入一次
3. 然后以相反的顺序在每个包中初始化常量和变量,如果包含有 init 函数的话,则调用该函数。
4. 在完成这一切之后main 也执行同样的过程,最后调用 main 函数开始执行程序
##4.2.6 转型
如果必要和可能的值可以转型(转换, 包裹成另一种类型的值。Go 语言没有隐式转换(自动),它必须明确说明,使用一个类似函数调用的语法(这里的类型可以看作是一种函数):
##4.2.6 类型转换
在必要以及可行的情况下,一个类型的值可以被转换成另一种类型的值。由于 Go 语言不存在隐式类型转换,因此所有的转换都必须显式说明,就像调用一个函数一样(类型在这里的作用可以看作是一种函数):
valueOfTypeB = typeB(valueOfTypeA)
类型B的值 = 类型B(类型A的值)
例子:
***译者注类型B的值 = 类型B(类型A的值)***
示例:
a := 5.0
b := int(a)
但这只能在定义正确的情况下成功,例如从一个窄型转换到一个宽型(例如int16 int32。当从一个宽型转换到窄型(例如int32 int16 或 float32 int值丢失(截断)会发生。当无法转型并且编译器检测到了这一点,会给出一个编译错误,否则发运行时错误。
但这只能在定义正确的情况下转换成功,例如从一个取值范围较小的类型转换到一个取值范围较大的类型(例如int16 转换为 int32。当从一个取值范围较大的转换到取值范围较小的类型时(例如int32 转换为 int16 或 float32 转换为 int,会发生精度丢失(截断)的情况。当编译器捕捉到非法的类型转换时会引发编译错误,否则将引发运行时错误。
变量是相同的基本类型可以相互转
具有相同底层类型的变量之间可以相互转
var a IZ = 5
c := int(a)
d := IZ(c)
##4.2.7 关于 Go 语言命名
干净,可读的代码和简洁性是 Go 开发的主要目标。gofmt 命令强化了代码风格。在 Go 语言中命名应该是简短的,简洁的,令人回味的。长名称命名使用大小写混合和下划线,像在 Java 或 Python 代码中那样,往往阻碍了可读性。名称不应包含包名:包名已经足够说明了。一个方法或函数返回的对象,其中函数被作为一个名词的名字命名,不应使用 Get...。若要更改一个对象请使用“SetName”。如果有必要Go 语言使用大小写混合 MixedCaps 或 mixedCaps而不是下划线连接多个名称。
##4.2.7 Go 命名规范
干净、可读的代码和简洁性是 Go 追求的主要目标。通过 gofmt 来强制实现统一的代码风格。Go 语言中对象的命名也应该是简洁且有意义的。像 Java 和 Python 中那样使用混合着大小写和下划线的冗长的名称会严重降低代码的可读性。名称不需要指出自己所属的包,因为在调用的时候会使用包名作为限定符。返回某个对象的函数或方法的名称一般都是使用名词,没有 “Get...” 之类的字符( ***译者注:个人觉得这个有点牵强*** ),如果是用于修改某个对象,则使用 “SetName”。有必须要的话可以使用大小写混合的方式如 MixedCaps 或 mixedCaps而不是使用下划线来分割多个名称。
##链接
- [目录](directory.md)