理解 Go 中包的可见性
目录
-
在 Go 中导入包 -
理解 Go 中包的可见性 -
如何在 Go 中编写条件语句 -
如何在 Go 中编写 Switch 语句 -
如何在 Go 中构造 for 循环 -
在循环中使用 Break 和 Continue -
如何在 Go 中定义并调用函数 -
如何在 Go 中使用可变参数函数 -
了解 Go 中的 defer -
了解 Go 中的 init -
用构建标签定制 Go 二进制文件 -
了解 Go 中的指针 -
在 Go 中定义结构体 -
在 Go 中定义方法 -
如何构建和安装 Go 程序 -
如何在 Go 中使用结构体标签 -
如何在 Go 使用 interface -
在不同的操作系统和架构编译 Go 应用 -
用 ldflags 设置 Go 应用程序的版本信息 -
在 Go 里面如何使用 Flag 包
介绍
当创建一个[Go 中的包]({ {< relref "/docs/21-How_To_Write_Packages_in_Go.md" >}})时,最终的目标通常是让其他开发者可以使用这个包,无论是高阶包还是整个程序。通过[导入包]({ {< relref "/docs/20-Importing_Packages_in_Go_DigitalOcean.md" >}}),你的这段代码可以作为其他更复杂的工具的构建模块。然而,只有某些包是可以导入的。这是由包的可见性决定的。
这里的可见性是指一个包或其他构造可以被引用的文件空间。例如,如果我们在一个函数中定义一个变量,那么这个变量的可见性(范围)只在定义它的那个函数中。同样,如果你在一个包中定义了一个变量,你可以让它只在该包中可见,或允许它在包外也可见。
在编写符合人体工程学的代码时,仔细控制包的可见性是很重要的,特别是在考虑到将来可能要对你的包进行修改时。如果你需要修复一个错误,提高性能,或改变功能,你会希望以一种不会破坏使用你的包的人的代码的方式进行改变。尽量减少破坏性修改的一个方法是只允许访问你的包中需要正常使用的部分。通过限制访问,你可以在内部对包进行修改,而减少影响其他开发者使用你的包的机会。
在这篇文章中,将学习如何控制包的可见性,以及如何保护代码中只应在包内使用的部分。为了做到这一点,我们将创建一个基本的记录器来记录和调试信息,使用具有不同程度的项目可见性的包。
前提条件
要遵循本文中的示例,你将需要:
-
按照[如何安装 Go 并设置本地编程环境]({ {< relref "/docs/01-How_To_Install_Go_and_Set_Up_a_Local Programming_Environment_on_Ubuntu_18.04_DigitalOcean.md" >}})设置的 Go 工作区。 本教程将使用以下文件结构:
.
├── bin
│
└── src
└── github.com
└── gopherguides
可导出与不可导出
不同于其他程序语言,如 Java 和Python使用访问修饰符如public
、private
或protected
来指定范围不同,Go 通过其声明方式来决定一个项目是否exported
和unxported
。在这种情况下,导出一个项目会使它在当前包之外是 "可见的"。如果它没有被导出,它只能在它被定义的包内可见和使用。
这种外部可见性是通过将声明的项目的第一个字母大写来控制的。所有以大写字母开头的声明,如 "类型"、"变量"、"常量"、"函数"等,在当前包外是可见的。
让我们看看下面的代码,仔细注意一下大写字母。
package greet
import "fmt"
var Greeting string
func Hello(name string) string {
return fmt.Sprintf(Greeting, name)
}
这段代码声明它是在greet
包中。然后声明了两个符号,一个叫做 Greeting
的变量和一个叫做 Hello
的函数。因为它们都以大写字母开头,所以它们都被 "可导出" 的,可供任何外部程序使用。如前所述,精心设计一个限制访问的包将允许更好的 API 设计,并使内部更新你的包更容易,而不会破坏任何依赖此包的代码。
定义包的可见性
为了仔细看看包的可见性在程序中是如何工作的,让我们创建一个logging
包,记住哪些信息我们希望包外可见,哪些我们不希望它可见。这个日志包将负责把我们程序的任何信息记录到控制台。它还将查看我们在什么级别上进行的日志记录,一个级别描述了日志的类型,它将是三种状态之一:信息
、警告
或错误
。
首先,在你的 src
目录下,创建一个名为 logging
的目录来放置日志文件:
mkdir logging
进入目录:
cd logging
然后,使用 nano 这样的编辑器,创建一个名为logging.go
的文件:
nano logging.go
在刚刚创建的logging.go
文件中写入以下代码: