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上编写哪些程序? 您是否在其中使用专有软件包?
