Go语言之包和文件

在Go语言中,包的作用和其他语言的库或者模块类似,Go语言的包我感觉类似于IDEA里面的module,就是可以互相调用的子工程的概念。用于支持模块化、封装、编译隔离和重用。一个包的源代码保存在一个或者多个以.go结尾的文件中,它所在目录名的尾部就是包的导入路径。

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

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

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

我们新建一个 tempconv的包,

 package tempconv
 ​
 import "fmt"
 ​
 type Celsius float64
 type Fahrenheit float64
 ​
 const(
     AbsoluteZeroC Celsius = -273.15
     FreezingC Celsius = 0
     BoilingC Celsius = 100
 )
 ​
 func (c Celsius) String() string{
     return fmt.Sprintf("%g°C",c)    
 }
 ​
 func (f Fahrenheit) String() string{
     return fmt.Springf("%g°F",f)
 }

我们把转换函数写在conv.go文件里面

 //CToF 把摄氏温度转换为华氏温度
 func CToF(c Celsius) Fahrenheit{
     return Fahrenheit(c*9/5 + 32)
 }
 //FTOC把华氏温度转换为摄氏温度
 func FToC(f Fahrenheit) Celsius{
     return Celsius((f-32) *5 /9)
 }

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

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

 fmt.Printf("Bad! %v\n",tempconv.AbsluteZeroc) //"Bad! -273.15°C"

如果我们需要使用tempconv包里的函数,只需要将我们写好的tempconv引入需要使用的包里即可,按照如下方式使用:

 fmt.Println(tempconv.CToF(tempconv.BoilingC)) // "212°F"

此外,我们应该养成一个好习惯,在每个包的前面用一段话对这个包进行简洁的描述。如果功能比较复杂,我们就需要单独新建一个文件,doc.go用该文件进行包的详细描述。

上一篇:浙大版《C语言程序设计(第3版)》题目集 练习2-4 温度转换 (5 分)


下一篇:团体程序设计天梯赛-练习集 L1-004 计算摄氏温度 (5 分)