Go程序设计语言2.6 包和文件-阿里云开发者社区

开发者社区> 华章计算机> 正文

Go程序设计语言2.6 包和文件

简介:
+关注继续查看

2.6 包和文件


在Go语言中包的作用和其他语言中的库或模块作用类似,用于支持模块化、封装、编译隔离和重用。一个包的源代码保存在一个或多个以.go结尾的文件中,它所在目录名的尾部就是包的导入路径,例如,gopl.io/ch1/helloworld包的文件存储在目录$GOPATH/src/gopl.io/ch1/helloworld中。

每一个包给它的声明提供独立的命名空间。例如,在image包中,Decode标识符和unicode/utf16包中的标识符一样,但是关联了不同的函数。为了从包外部引用一个函数,我们必须明确修饰标识符来指明所指的是image.Decode或utf16.Decode。

包让我们可以通过控制变量在包外面的可见性或导出情况来隐藏信息。在Go里,通过一条简单的规则来管理标识符是否对外可见:导出的标识符以大写字母开头。

为了说明基本原理,假设温度转换软件很受欢迎,我们想把它作为新包贡献给Go社区,将要怎么做呢?

我们创建一个叫作gopl.io/ch2/tempconv的包,这是前面例子的变种(这里我们没有照惯例对例子进行顺序编号,目的是让包路径更实际一些)。包自己保存在两个文件里,以展示如何访问一个包里面多个独立文件中的声明。现实中,像这样的小包可能只需要一个文件。

将类型、它们的常量及方法的声明放在tempconv.go中:

 

 

将转换函数放在conv.go中:

 

每一个文件的开头用package声明定义包的名称。当导入包时,它的成员通过诸如tempconv.CToF等方式被引用。如果包级别的名字(像类型和常量)在包的一个文件中声明,就像所有的源代码在同一个文件中一样,它们对于同一个包中的其他文件可见。注意,tempconv.go导入fmt包,但是conv.go没有,因为它本身没有用到fmt包。

因为包级别的常量名字以大写字母开头,所以它们也可以使用修饰过的名称(如tempconv.AbsoluteZeroC)来访问:

 

为了在某个包里将摄氏温度转换为华氏温度,导入包gopl.io/ch2/tempconv,然后编写下面的代码:

 

package声明前面紧挨着的文档注释(参考10.7.4节)对整个包进行描述。习惯上,应该在开头用一句话对包进行总结性的描述。每一个包里只有一个文件应该包含该包的文档注释。扩展的文档注释通常放在一个文件中,按惯例名字叫作doc.go。

练习2.1:添加类型、常量和函数到tempconv包中,处理以开尔文为单位(K)的温度值,0K=-273.15℃,变化1K和变化1℃是等价的。

2.6.1 导入

在Go程序里,每一个包通过称为导入路径(import path)的唯一字符串来标识。它们出现在诸如"gopl.io/ch2/tempconv"之类的import声明中。语言的规范没有定义哪些字符串从哪来以及它们的含义,这依赖于工具来解释。当使用go工具(参考第10章)时,一个导入路径标注一个目录,目录中包含构成包的一个或多个Go源文件。除了导入路径之外,每个包还有一个包名,它以短名字的形式(且不必是唯一的)出现在包的声明中。按约定,包名匹配导入路径的最后一段,这样可以方便地预测gopl.io/ch2/tempconv的包名是tempconv。

为了使用gopl.io/ch2/tempconv,必须导入它:

 

导入声明可以给导入的包绑定一个短名字,用来在整个文件中引用包的内容。上面的import可以使用修饰标识符来引用gopl.io/ch2/tempconv包里的变量名,如tempconv.CToF。默认这个短名字是包名,在本例中是tempconv,但是导入声明可以设定一个可选的名字来避免冲突(参考10.4节)。

cf程序将一个数字型的命令行参数分别转换成摄氏温度和华氏温度:

 

如果导入一个没有被引用的包,就会触发一个错误。这个检查帮助消除代码演进过程中不再需要的依赖(尽管它在调试过程中会带来一些麻烦),因为注释掉一条诸如log.Print("got here!")之类的代码,可能去除了对于log包唯一的一个引用,导致编译器报错。这种情况下,需要注释掉或者删掉不必要的import。

练习2.2:写一个类似于cf的通用的单位转换程序,从命令行参数或者标准输入(如果没有参数)获取数字,然后将每一个数字转换为以摄氏温度和华氏温度表示的温度,以英寸和米表示的长度单位,以磅和千克表示的重量,等等。

2.6.2 包初始化

包的初始化从初始化包级别的变量开始,这些变量按照声明顺序初始化,在依赖已解析完毕的情况下,根据依赖的顺序进行。

 

如果包由多个.go文件组成,初始化按照编译器收到文件的顺序进行:go工具会在调用编译器前将.go文件进行排序。

对于包级别的每一个变量,生命周期从其值被初始化开始,但是对于其他一些变量,比如数据表,初始化表达式不是简单地设置它的初始化值。这种情况下,init函数的机制会比较简单。任何文件可以包含任意数量的声明如下的函数:

 

这个init函数不能被调用和被引用,另一方面,它也是普通的函数。在每一个文件里,当程序启动的时候,init函数按照它们声明的顺序自动执行。

包的初始化按照在程序中导入的顺序来进行,依赖顺序优先,每次初始化一个包。因此,如果包p导入了包q,可以确保q在p之前已完全初始化。初始化过程是自下向上的,main包最后初始化。在这种方式下,在程序的main函数开始执行前,所有的包已初始化完毕。

下面的包定义了一个PopCount函数,它返回一个数字中被置位的个数,即在一个uint64的值中,值为1的位的个数,这称为种群统计。它使用init函数来针对每一个可能的8位值预计算一个结果表pc,这样PopCount只需要将8个快查表的结果相加而不用进行64步的计算。(这个不是最快的统计位算法,只是方便用来说明init函数,用来展示如何预计算一个数值表,它是一种很有用的编程技术。)

 

注意,init中的range循环只使用索引;值不是必需的,所以没必要包含进来。循环可以重写为下面的形式:

 

我们将在下一节和10.5节看到init函数的其他用途。

练习2.3:使用循环重写PopCount来代替单个表达式。对比两个版本的效率。(11.4节会展示如何系统性地对比不同实现的性能。)

练习2.4:写一个用于统计位的PopCount,它在其实际参数的64位上执行移位操作,每次判断最右边的位,进而实现统计功能。把它与快查表版本的性能进行对比。

练习2.5:使用x&(x-1)可以清除x最右边的非零位,利用该特点写一个PopCount,然后评价它的性能。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
C语言及程序设计初步例程-42 将数据输出到文本文件
贺老师教学链接  C语言及程序设计初步 本课讲解 文件的操作步骤 #include <stdio.h> #include <stdlib.h> int main() { FILE *fp; int i, d; fp=fopen("data.txt","w"); if(fp==NULL) { printf("Fi
873 0
C语言程序设计实践(OJ)-全局变量、文件操作
2969:学生成绩的处理 Description   编写一个函数void calcscore(int n),在函数中输入n个人的成绩,计算最高分,最低分,总分和平均分,要求在主函数中调用函数calcscore计算各种成绩,并在主函数中输出各种计算结果。(使用全局变量在函数之间传递多个数据) #include <stdio.h> double HighS
1147 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
4617 0
C语言及程序设计实践项目-递归和多文件组织
【项目1——递归求解】 (1)立方累加和:用递归函数求f(n)=1 3 +2 3 +...+n 3  f(n)=1^3+2^3+...+n^3,要求先将f(n)数学表达式表示成递归的形式,然后再编程序实现。 (2)写出求1*3*…*n的递归式,并编写出递归函数求解。 (3)编程序,用递归函数求出两个数的最大公约数。(包括编main函数,调用定义的递归函数) 参考解答
1022 0
《UNIXLinux程序设计教程》一3.1 文件描述字的打开、创建和关闭
本节书摘来自华章出版社《UNIXLinux程序设计教程》一 书中的第3章,第3.1节,作者:赵克佳 沈志宇,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
951 0
10059
文章
0
问答
来源圈子
更多
+ 订阅
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载