Go程序包由位于同一目录中的Go文件组成,该文件的开头有相同的
package表达式。 连接到程序的程序包使您可以扩展其功能。 一些软件包是标准Go库的一部分。 这意味着,如果您使用Go,则它们已经安装。 其他软件包使用
go get命令安装。 您还可以编写自己的Go-packages,在特殊目录中创建文件,并遵守包设计规则。

我们今天发布的翻译材料是Go-package的开发指南,可以将Go-packages连接到其他文件。
先决条件
- 设置您的Go软件环境( 在此处了解如何执行此操作)。 创建一个Go工作区(以上材料的第五点专门讨论这一点)。 在本材料的下一部分中,您可以找到建议在家中复制的示例。 因此,您可以更好地处理它们。
- 为了加深您对
GOPATH -请阅读此材料。
编写和导入包
编写程序包代码与编写常规Go代码相同。 包可以包含函数,类型和变量的声明,然后可以在其他Go程序中使用它们。
在开始创建新程序包之前,我们需要转到Go工作区。 它位于
GOPATH变量指定的路径上。 例如,将我们的组织称为
gopherguides 。 同时,我们使用
GitHub作为存储库。 这导致以下事实:沿着
GOPATH指定的路径,我们具有以下文件夹结构:
└── $GOPATH └── src └── github.com └── gopherguides
我们将命名我们将在本指南中开发的软件包。 为此,请在
gopherguides目录中创建
greet目录。 因此,现有的文件夹结构将采用以下形式:
└── $GOPATH └── src └── github.com └── gopherguides └── greet
现在我们准备将第一个文件添加到
greet目录。 通常,作为包的入口点的文件称为与包目录相同的文件。 在这种情况下,这意味着我们在
greet目录中创建
greet.go文件:
└── $GOPATH └── src └── github.com └── gopherguides └── greet └── greet.go
在此文件中,我们可以编写要在项目中重用的代码。 在这种情况下,我们将创建
Hello函数,该函数显示文本
Hello, World! 。
在文本编辑器中打开
greet.go文件,并向其中添加以下代码:
package greet import "fmt" func Hello() { fmt.Println("Hello, World!") }
让我们分析该文件的内容。 每个文件的第一行应包含我们在其中工作的软件包的名称。 由于我们位于
greet package ,因此在此处使用
package关键字,后跟包名称:
package greet
这告诉编译器接受文件中的所有内容作为
greet软件包的一部分。
接下来,使用
import语句导入必要的软件包。 在这种情况下,我们只需要一个软件包
fmt :
import "fmt"
最后,我们创建
Hello函数。 她将使用
fmt软件包的功能来显示字符串
Hello, World! :
func Hello() { fmt.Println("Hello, World!") }
现在,在创建
greet包之后,您可以在其他任何包中使用它。 让我们创建一个新的包,在其中我们将使用
greet包。
即,我们将创建一个
example包。 为此,我们将从进行相同的假设开始,创建
greet包。 首先,在
gopherguides文件夹中创建
example文件夹:
└── $GOPATH └── src └── github.com └── gopherguides └── example
现在创建一个文件,作为包的入口点。 我们将此软件包视为可执行程序,而不是其代码计划在其他软件包中使用的软件包。 程序输入点的文件通常称为
main.go :
└── $GOPATH └── src └── github.com └── gopherguides └── example └── main.go
在编辑器中打开
main.go文件,
main.go以下代码
main.go到其中,这使您可以使用
greet包的功能:
package main import "github.com/gopherguides/greet" func main() { greet.Hello() }
我们将
greet包导入了
main.go文件中,这意味着要调用此包中声明的函数,我们需要使用点表示法。 点表示法是一种结构,其中在包名称和要使用的此包的资源名称之间放置一个点。 例如,在
greet包中,
Hello函数扮演资源的角色。 如果需要调用此函数,则使用点表示法
: greet.Hello() 。
现在,您可以打开终端并运行程序:
go run main.go
完成此操作后,终端将显示以下内容:
Hello, World!
现在让我们谈谈如何使用包中声明的变量。 为此,请将变量声明添加到
greet.go文件中:
package greet import "fmt" var Shark = "Sammy" func Hello() { fmt.Println("Hello, World!") }
打开
main.go文件,并在其中添加一行,其中
fmt.Println()函数用于显示在
greet.go程序包中声明的
Shark变量的值。 即,将
main.go转换为以下格式:
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) }
再次运行程序:
go run main.go
现在,她将输出以下内容:
Hello, World! Sammy
现在让我们谈谈如何在包中声明类型。 使用“
Name和“
Color字段创建一个
Octopus类型,并创建一个类型方法。 调用此方法时,将返回经过特殊处理的
Octopus字段的内容。 让我们
greet.go转换为以下格式:
package greet import "fmt" var Shark = "Sammy" type Octopus struct { Name string Color string } func (o Octopus) String() string { return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color) } func Hello() { fmt.Println("Hello, World!") }
现在打开
main.go ,在其中创建新类型结构的实例,并引用其
String()方法:
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) oct := greet.Octopus{ Name: "Jesse", Color: "orange", } fmt.Println(oct.String()) }
在使用类似于
oct := greet.Octopus的构造创建
Octopus实例之后,可以从
main.go文件的命名空间访问该类型的方法和属性。 特别是,这使您可以使用位于
main.go文件末尾的
oct.String()命令,而
main.go greet 。 另外,例如,我们可以使用
oct.Color构造来
oct.Color Color结构的字段。 同时,当我们调用该方法时,我们不访问
greet 。
Octopus类型的
String方法使用
fmt.Sprintf函数构成句子,并使用
return ,结果字符串
return给方法调用(在这种情况下,此位置位于
main.go )。
再次运行程序:
go run main.go
它将输出以下内容到控制台:
Hello, World! Sammy The octopus's name is "Jesse" and is the color orange.
现在,我们为Octopus配备了
String方法,我们有了适合重用的类型信息输出机制。 如果将来您需要更改此方法的行为(可在许多项目中使用),则只需在
greet.go编辑其代码
greet.go 。
实体出口
您可能已经注意到,在访问
greet软件包时,我们使用的所有内容都以大写字母开头的名称。 Go没有其他语言的访问修饰符,例如
public ,
private或
protected 。 实体对外部机制的可见性受字母(大小)开头的事实控制。 结果,名称,名称和名称以大写字母开头的类型,变量,函数在当前程序包外部可用。 包外部可见的代码称为导出。
如果为
Octopus类型配备了称为
reset的新方法,则可以从
greet包中调用此方法,但不能从
greet包中的
main.go文件中
main.go 。 这是
greet.go的更新版本:
package greet import "fmt" var Shark = "Sammy" type Octopus struct { Name string Color string } func (o Octopus) String() string { return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color) } func (o Octopus) reset() { o.Name = "" o.Color = "" } func Hello() { fmt.Println("Hello, World!") }
让我们尝试从
main.go文件中调用
reset :
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) oct := greet.Octopus{ Name: "Jesse", Color: "orange", } fmt.Println(oct.String()) oct.reset() }
这将导致以下编译错误:
oct.reset undefined (cannot refer to unexported field or method greet.Octopus.reset)
为了导出
Octopus类型
reset方法,您需要对其进行重命名,将首字母小写
r替换为大写
R 我们通过编辑
greet.go做到这
greet.go :
package greet import "fmt" var Shark = "Sammy" type Octopus struct { Name string Color string } func (o Octopus) String() string { return fmt.Sprintf("The octopus's name is %q and is the color %s.", o.Name, o.Color) } func (o Octopus) Reset() { o.Name = "" o.Color = "" } func Hello() { fmt.Println("Hello, World!") }
这将导致以下事实:我们将能够从其他程序包调用
Reset ,而不会遇到错误消息:
package main import ( "fmt" "github.com/gopherguides/greet" ) func main() { greet.Hello() fmt.Println(greet.Shark) oct := greet.Octopus{ Name: "Jesse", Color: "orange", } fmt.Println(oct.String()) oct.Reset() fmt.Println(oct.String()) }
运行程序:
go run main.go
这是控制台的内容:
Hello, World! Sammy The octopus's name is "Jesse" and is the color orange The octopus's name is "" and is the color .
通过调用
Reset方法,我们清除了
Octopus实例的“
Name和“
Color字段。 结果,在调用
String ,以前显示了
Name和
Color字段的内容,现在什么也不显示。
总结
编写Go软件包与编写常规Go代码没什么不同。 但是,将程序包代码放在其自己的目录中可以隔离该代码,该代码可在任何其他Go项目中使用。 在这里,我们讨论了如何在程序包中声明函数,变量和类型,研究了如何在程序包外部使用这些实体,并弄清楚了存储在何处以供重用的程序包。
亲爱的读者们! 您通常在Go上编写哪些程序? 您是否在其中使用专有软件包?
