前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >10.Go语言-包

10.Go语言-包

原创
作者头像
面向加薪学习
发布2022-09-04 10:27:11
2720
发布2022-09-04 10:27:11
举报
文章被收录于专栏:面向加薪学习面向加薪学习

第 10 章 包

包(package) 用于组织 Go 源代码,提供了更好的可重用性与可读性。Go 语言有超过 100 个的标准包,可以用 go list std | wc -l 命令查看标准包的具体数目,标准库为大多数的程序提供了必要的基础组件。

10.1 main 包

首先,我们先来看看 main 包,该包中包含一个 main() 函数,该函数是程序运行的入口。

package packagename 代码指定了某一源文件属于某一个包。它应该放在每一个源文件的第一行。例如我们 Go 的第一个程序。

代码语言:go
复制
// hello go
package main

import "fmt"

func main() {
    fmt.Println("《Go语言极简一本通》")
}

package main 这一行指定该文件属于 main 包。import "fmt" 语句用于导入一个已存在的名为 fmt 的包。

10.2 创建包

下面我们创建自定义的 book 包,其中,属于某一个包的源文件都应该放置于一个单独命名的文件夹里,按照 Go 的惯例,应该用包名命名该文件夹。所以应当先创建一个 book 文件夹,位于该目录下创建一个 book.go 源文件,里面实现我们自定义的数学加法函数。请注意函数名的首字母要大写。

代码语言:go
复制
// book.go
package book

func ShowBookInfo(bookName, authorName string) (string, error) {
	if bookName == "" {
		return "", errors.New("图书名称为空")
	}
	if authorName == "" {
		return "", errors.New("作者名称为空")
	}
	return bookName + ",作者:" + authorName, nil
}

Tips:

  • 导出名字(Exported Names)
    • 我们将 book 包中的函数 ShowBookInfo 首字母大写。在 Go 中这具有特殊意义。在 Go 中,任何以大写字母开头的变量或者函数都是被导出的名字。其它包只能访问被导出的函数和变量。在这里,我们需要在 main 包中访问 ShowBookInfo 函数,因此会将它们的首字母大写。
    • 如果在 book.go 中将函数名从 ShowBookInfo 变为 showBookInfo ,并且在 main.go 中调用 book.showBookInfo 函数,则该程序编译不通过。因为如果想在包外访问一个函数,它应该首字母大写。

10.3 导入包

使用包之前我们需要导入包,在 GoLand 中会帮你自动导入所需要的包。导入包的语法为 import path ,其中 path 可以是相对于工作区文件夹的相对路径,也可以是绝对路径。

代码语言:go
复制
package main

import (
	"fmt"
	"book"
)

func main() {
	bookName := "《Go语言极简一本通》"
	author := "欢喜"
	bookInfo, _ := book.ShowBookInfo(bookName, author)
	fmt.Println("bookInfo = ", bookInfo)
}

导入包可以单行导入也可以多行导入,像上面的程序代码就是多行导入的例子,一般我们也建议使用多行导入,当然你也可以使用单行导入:

代码语言:go
复制
import "fmt"
import "book"

10.4 使用别名

如果我们导入了两个具有同一包名的包时会产生冲突,这时我们可以为其中一个包定义别名:

代码语言:go
复制
import (
    "crypto/rand"
    mrand "math/rand" // 将名称替换为 mrand 避免冲突
)

当然,我们也可以使用别名代替名字很长的包名。

10.5 使用点操作

导入一个包后,如果要使用该包中的函数,都要使用 包名.方法名 语法进行调用,对于一些使用高频的包,例如 fmt 包,每次调用打印函数时都要使用 fmt.Println() 进行调用,很不方便。我们可以在导入包的时,使用 import . package_path 语法。从此,我们打印再也不用加 fmt 了。

代码语言:go
复制
import . "fmt"

func main() {
    Println("hello, world")
}

但这种用法,会有一定的隐患,就是导入的包里可能有函数,会和我们自己的函数发生冲突。

10.6 包的初始化

每个包都允许有一个或多个 init 函数, init 函数不应该有任何返回值类型和参数,在代码中也不能显式调用它,当这个包被导入时,就会执行这个包的 init 函数,做初始化任务, init 函数优先于 main 函数执行。该函数形式如下:

代码语言:go
复制
func init() {
}

包的初始化顺序:首先初始化 包级别(Package Level) 的变量,紧接着调用 init 函数。包可以有多个 init 函数(在一个文件或分布于多个文件中),它们按照编译器解析它们的顺序进行调用。如果一个包导入了另一个包,会先初始化被导入的包。尽管一个包可能会被导入多次,但是它只会被初始化一次。

10.7 包的匿名导入

之前说过,导入一个没有使用的包编译会报错。但有时候我们只是想执行包里的 init 函数来执行一些初始化任务的话应该怎么办呢?

我们可以使用匿名导入的方法,使用 空白标识符(Blank Identifier)

代码语言:go
复制
import _ "fmt"

由于导入时会执行该包里的 init 函数,所以编译仍会将此包编译到可执行文件中。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第 10 章 包
    • 10.1 main 包
      • 10.2 创建包
        • 10.3 导入包
          • 10.4 使用别名
            • 10.5 使用点操作
              • 10.6 包的初始化
                • 10.7 包的匿名导入
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档