跳转到主要内容

标签(标签)

资源精选(342) Go开发(108) Go语言(103) Go(99) angular(82) LLM(75) 大语言模型(63) 人工智能(53) 前端开发(50) LangChain(43) golang(43) 机器学习(39) Go工程师(38) Go程序员(38) Go开发者(36) React(33) Go基础(29) Python(24) Vue(22) Web开发(20) Web技术(19) 精选资源(19) 深度学习(19) Java(18) ChatGTP(17) Cookie(16) android(16) 前端框架(13) JavaScript(13) Next.js(12) 安卓(11) 聊天机器人(10) typescript(10) 资料精选(10) NLP(10) 第三方Cookie(9) Redwoodjs(9) LLMOps(9) Go语言中级开发(9) 自然语言处理(9) PostgreSQL(9) 区块链(9) mlops(9) 安全(9) 全栈开发(8) ChatGPT(8) OpenAI(8) Linux(8) AI(8) GraphQL(8) iOS(8) 软件架构(7) Go语言高级开发(7) AWS(7) C++(7) 数据科学(7) whisper(6) Prisma(6) 隐私保护(6) RAG(6) JSON(6) DevOps(6) 数据可视化(6) wasm(6) 计算机视觉(6) 算法(6) Rust(6) 微服务(6) 隐私沙盒(5) FedCM(5) 语音识别(5) Angular开发(5) 快速应用开发(5) 提示工程(5) Agent(5) LLaMA(5) 低代码开发(5) Go测试(5) gorm(5) REST API(5) 推荐系统(5) WebAssembly(5) GameDev(5) CMS(5) CSS(5) machine-learning(5) 机器人(5) 游戏开发(5) Blockchain(5) Web安全(5) Kotlin(5) 低代码平台(5) 机器学习资源(5) Go资源(5) Nodejs(5) PHP(5) Swift(5) 智能体(4) devin(4) Blitz(4) javascript框架(4) Redwood(4) GDPR(4) 生成式人工智能(4) Angular16(4) Alpaca(4) 编程语言(4) SAML(4) JWT(4) JSON处理(4) Go并发(4) kafka(4) 移动开发(4) 移动应用(4) security(4) 隐私(4) spring-boot(4) 物联网(4) nextjs(4) 网络安全(4) API(4) Ruby(4) 信息安全(4) flutter(4) 专家智能体(3) Chrome(3) CHIPS(3) 3PC(3) SSE(3) 人工智能软件工程师(3) LLM Agent(3) Remix(3) Ubuntu(3) GPT4All(3) 软件开发(3) 问答系统(3) 开发工具(3) 最佳实践(3) RxJS(3) SSR(3) Node.js(3) Dolly(3) 移动应用开发(3) 低代码(3) IAM(3) Web框架(3) CORS(3) 基准测试(3) Go语言数据库开发(3) Oauth2(3) 并发(3) 主题(3) Theme(3) earth(3) nginx(3) 软件工程(3) azure(3) keycloak(3) 生产力工具(3) gpt3(3) 工作流(3) C(3) jupyter(3) 认证(3) prometheus(3) GAN(3) Spring(3) 逆向工程(3) 应用安全(3) Docker(3) Django(3) R(3) .NET(3) 大数据(3) Hacking(3) 渗透测试(3) C++资源(3) Mac(3) 微信小程序(3) Python资源(3) JHipster(3) 大型语言模型(2) 语言模型(2) 可穿戴设备(2) JDK(2) SQL(2) Apache(2) Hashicorp Vault(2) Spring Cloud Vault(2) Go语言Web开发(2) Go测试工程师(2) WebSocket(2) 容器化(2) AES(2) 加密(2) 输入验证(2) ORM(2) Fiber(2) Postgres(2) Gorilla Mux(2) Go数据库开发(2) 模块(2) 泛型(2) 指针(2) HTTP(2) PostgreSQL开发(2) Vault(2) K8s(2) Spring boot(2) R语言(2) 深度学习资源(2) 半监督学习(2) semi-supervised-learning(2) architecture(2) 普罗米修斯(2) 嵌入模型(2) productivity(2) 编码(2) Qt(2) 前端(2) Rust语言(2) NeRF(2) 神经辐射场(2) 元宇宙(2) CPP(2) 数据分析(2) spark(2) 流处理(2) Ionic(2) 人体姿势估计(2) human-pose-estimation(2) 视频处理(2) deep-learning(2) kotlin语言(2) kotlin开发(2) burp(2) Chatbot(2) npm(2) quantum(2) OCR(2) 游戏(2) game(2) 内容管理系统(2) MySQL(2) python-books(2) pentest(2) opengl(2) IDE(2) 漏洞赏金(2) Web(2) 知识图谱(2) PyTorch(2) 数据库(2) reverse-engineering(2) 数据工程(2) swift开发(2) rest(2) robotics(2) ios-animation(2) 知识蒸馏(2) 安卓开发(2) nestjs(2) solidity(2) 爬虫(2) 面试(2) 容器(2) C++精选(2) 人工智能资源(2) Machine Learning(2) 备忘单(2) 编程书籍(2) angular资源(2) 速查表(2) cheatsheets(2) SecOps(2) mlops资源(2) R资源(2) DDD(2) 架构设计模式(2) 量化(2) Hacking资源(2) 强化学习(2) flask(2) 设计(2) 性能(2) Sysadmin(2) 系统管理员(2) Java资源(2) 机器学习精选(2) android资源(2) android-UI(2) Mac资源(2) iOS资源(2) Vue资源(2) flutter资源(2) JavaScript精选(2) JavaScript资源(2) Rust开发(2) deeplearning(2) RAD(2)

介绍

一个包由位于同一目录中的 Go 文件组成,并且在开头具有相同的包语句。您可以从包中包含其他功能,以使您的程序更加复杂。一些包可通过 Go 标准库获得,因此随 Go 安装一起安装。其他的可以用 Go 的 go get 命令安装。您还可以通过使用必要的包语句在要共享代码的同一目录中创建 Go 文件来构建自己的 Go 包。

本教程将指导您编写 Go 包以在其他编程文件中使用。

先决条件

 

  • 按照如何安装和设置 Go 系列的本地编程环境中的教程之一设置 Go 编程环境。按照本地编程环境教程中的第 5 步创建您的 Go 工作区。要遵循本文中的示例和命名约定,请阅读第一部分编写和导入包。
  • 要加深您对 GOPATH 的了解,请阅读我们的文章了解 GOPATH。


编写和导入包


编写一个包就像编写任何其他 Go 文件一样。包可以包含函数、类型和变量的定义,然后可以在其他 Go 程序中使用。

在我们创建一个新包之前,我们需要进入我们的 Go 工作区。这通常在我们的 gopath 下。例如,在本教程中,我们将调用包 greet。为此,我们在项目空间下的 gopath 中创建了一个名为 greet 的目录。如果我们的组织是 gopherguides,并且我们想在组织下创建 greet 包,同时使用 Github 作为我们的代码存储库,那么我们的目录将如下所示:

└── $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 的函数来打印 Hello World。

在文本编辑器中打开 greet.go 文件并添加以下代码:

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 包:

main.go

package main

import "github.com/gopherguides/greet"

func main() {
	greet.Hello()
}

因为您正在导入一个包,所以您需要通过以点表示法引用包名称来调用该函数。点符号是放置句号的做法。在您正在使用的包的名称和您要使用的包中的资源之间。例如,在你的 greet 包中,你有 Hello 函数作为资源。如果要调用该资源,请使用 greet.Hello() 的点表示法。

现在,您可以打开终端并在命令行上运行程序:

go run main.go


完成后,您将收到以下输出:

Output
Hello, World!

要了解如何在包中使用变量,让我们在 greet.go 文件中添加一个变量定义:

greet.go

package greet

import "fmt"

var Shark = "Sammy"

func Hello() {
    fmt.Println("Hello, World!")
}

接下来,打开您的 main.go 文件并添加以下突出显示的行以在 fmt.Println() 函数中从 greet.go 调用变量:

main.go

package main

import (
    "fmt"

    "github.com/gopherguides/greet"
)

func main() {
    greet.Hello()

    fmt.Println(greet.Shark)
}

再次运行程序后:

go run main.go


您将收到以下输出:

Output
Hello, World!
Sammy


最后,让我们在 greet.go 文件中定义一个类型。您将创建带有名称和颜色字段的 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 在文件末尾创建该类型的实例:

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。例如,您还可以调用类型字段之一,例如 oct.Color 而不引用 greet 包的名称。

Octopus 类型的 String 方法使用 fmt.Sprintf 函数创建一个句子,并将结果以字符串形式返回给调用者(在本例中为您的主程序)。

运行程序时,您将收到以下输出:

go run main.go

Output
Hello, World!
Sammy
The octopus's name is "Jesse" and is the color orange.


通过在 Octopus 上创建 String 方法,您现在有了一种可重用的方式来打印有关您的自定义类型的信息。如果你想在以后改变这个方法的行为,你只需要编辑这个方法。

导出的代码


您可能已经注意到,您调用的 greet.go 文件中的所有声明都是大写的。 Go 不像其他语言那样具有公共、私有或受保护修饰符的概念。外部可见性由大小写控制。以大写字母开头的类型、变量、函数等在当前包之外是公开可用的。在其包外可见的符号被视为已导出。

如果你向 Octopus 添加一个名为 reset 的新方法,你可以在 greet 包中调用它,但不能从在 greet 包之外的 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:

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.reset()
}

您将收到以下编译错误:

Output
oct.reset undefined (cannot refer to unexported field or method greet.Octopus.reset)


要从 Octopus 导出重置功能,请将重置中的 R 大写:

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 而不会出现错误:

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.Reset()

    fmt.Println(oct.String())
}

现在如果你运行程序:

go run main.go


您将收到以下输出:

Output
Hello, World!
Sammy
The octopus's name is "Jesse" and is the color orange
The octopus's name is "" and is the color .


通过调用重置,您清除了名称和颜色字段中的所有信息。当您调用 String 方法时,它不会在 Name 和 Color 通常出现的地方打印任何内容,因为这些字段现在是空的。

结论


编写 Go 包与编写任何其他 Go 文件相同,但是将其放在另一个目录中可以隔离代码以在其他地方重用。本教程介绍了如何在包中编写定义,演示了如何在另一个 Go 编程文件中使用这些定义,并解释了将包保存在何处以便访问它的选项。

文章链接