各位Gopher们,今天将是《How To Code In Go》上半部分的最后一篇啦!在这里小G先给 Gopher 们一直以来的坚持点个大大的赞!行百里者半九十,要继续坚持哦!
Gopher们在学习过程中若是有任何与Go相关的问题,欢迎留言区告诉我们,小G看到后一定第一时间回复大家!
-
如何在 Ubuntu 18.04 上安装 Go 和设置本地编程环境
-
如何在 macOS 上安装 Go 和设置本地编程环境
-
如何在 Windows 10 上安装 Go 和设置本地编程环境
-
如何用 Go 编写你的第一个程序
-
理解 GOPATH
-
如何在 Go 中写注释
-
理解 Go 的数据类型
-
Go 中处理字符串的介绍
-
如何在 Go 中格式化字符串
-
介绍 Go 中的 Strings 包
-
如何在 Go 中使用变量和常量
-
如何在 Go 中转换数据类型
-
如何用运算符在 Go 中做数学计算
-
了解 Go 中的布尔逻辑
-
理解 Go 中的 Map
-
理解 Go 中的数组和切片
-
在 Go 中处理错误
-
在 Go 中创建自定义错误
-
在 Go 中处理恐慌
-
在 Go 中导入包
如何在 Go 中编写包
一个包由同一目录下的 Go 文件组成的,并且在文件开头有相同的包声明。你可以从包中加入额外的功能,使你的程序更加复杂。有些包可以通过 Go 标准库获得,因此在安装 Go 时就已经安装了。其他的可以用 Go 的go get
命令来安装。你也可以通过在同一目录下创建 Go 文件来建立你自己的 Go 包,你可以通过使用必要的包声明来分享代码。
前提条件
-
按照《如何安装和设置 Go 的本地编程环境》系列教程中的一个教程设置 Go 编程环境。按照本地编程环境教程中的步骤5创建你的 Go 工作区。要遵循本文的例子和命名规则,请阅读第一节「编写和导入软件包」。 -
为了加深你对 GOPATH 的了解,请阅读往期文章《理解 GOPATH》。
编写和导入软件包
在我们创建一个新的包之前,我们需要进入我们的 Go 工作区。这通常是在我们的gopath
下。对于这个例子,本教程中我们将把包称为greet
。为了做到这一点,在我们的项目空间下的gopath
中创建了一个名为greet
的目录。当使用 Github 作为代码库,组织名称为gopherguides
,想在此组织下创建greet
包,那么我们的目录会是这样的:
└── $GOPATH
└── src
└── github.com
└── gopherguides
greet
目录在gopherguides
目录中:└── $GOPATH
└── src
└── github.com
└── gopherguides
└── greet
主要
或 入口
文件是以目录名来命名的。在这种情况下,将在greet
目录下创建一个名为greet.go
的文件:└── $GOPATH
└── src
└── github.com
└── gopherguides
└── greet
└── greet.go
Hello World
的 Hello
的函数。greet.go
文件,增加如下代码:package greet
import "fmt"
func Hello() {
fmt.Println("Hello, World!")
}
让我们把这个文件分解一下,每个文件中第一行需要是所处的包
名称。因为你在greet
包里,所以通过使用package
关键字,后面加包的名称:
package greet
greet
包的一部分。import
语句声明你需要使用的任何其他包。在这个文件中你只使用一个包,fmt
包:import "fmt"
Hello
,它将使用fmt
包来打印出Hello, World!
。func Hello() {
fmt.Println("Hello, World!")
}
greet
包,可以在你创建的任何其他包中使用它。让我们创建一个新的包,在其中使用greet
包。example
的包,这意味着需要一个名为example
的目录。在gopherguides
中创建这个包,所以目录结构看起来像这样:└── $GOPATH
└── src
└── github.com
└── gopherguides
└── example
main.go
:└── $GOPATH
└── src
└── github.com
└── gopherguides
└── example
└── main.go
main.go
,添加以下代码来调用greet
包:package main
import "github.com/gopherguides/greet"
func main() {
greet.Hello()
}
因为正在导入一个包,通过用点符号来调用指定包的函数。点符号是指在使用的包的名称和想使用的包中资源之间加一个句号.
。例如,在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
中的变量:package main
import (
"fmt"
"github.com/gopherguides/greet"
)
func main() {
greet.Hello()
fmt.Println(greet.Shark)
}
go run main.go
Hello, World!
Sammy
最后,让我们也在greet.go
文件中定义一个类型。创建一个带有 name
和 color
字段的 Octopus
类型,以及一个在调用时将打印出字段的函数:
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
,在文件的末尾创建一个该类型的实例: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
文件的命名空间中访问该类型的函数和字段。这使得在最后一行直接写oct.String()
,而不用调用greet
。同样的,也可以在不引用greet
包的名字的情况下调用oct.Color
等类型字段。Octopus
类型上的String
方法使用fmt.Sprintf
函数来输出一段文本,并将结果即一个字符串,返回
给调用者(在这里是指主程序)。
go run main.go
Hello, World!
Sammy
The octopus's name is "Jesse" and is the color orange.
Octopus
上创建String
方法,你现在有一个可重复使用的方法来打印出自定义类型的信息。如果想在将来改变这个方法的行为,只需要编辑这一个方法。可导出代码
greet.go
文件中所有的声明都是大写的。Go 没有像其他语言那样有public
、private
或protected
修饰符的概念。外部可见性是由大写字母控制的。以大写字母开头的类型、变量、函数等等,在当前包之外是可以公开使用的。一个在其包外可见的符号被认为是 可导出
的。Octopus
添加了一个名为reset
的新方法,可以在greet
包内调用它,但是不能在main.go
文件中调用,因为调用者在greet
包之外: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
功能,请将reset
中的R
大写: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!")
}
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
,清除了Name
和Color
字段中的所有信息。当调用String
方法时,Name
和Color
打印为空,因为这些字段现在是空的。总结
2022 GopherChina大会报名火热进行中!
大会合作、现场招聘及企业购票等事宜请联系微信:18516100522
戳这里 Go !
原文始发于微信公众号(GoCN):「每周译Go」如何在 Go 中编写包
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论