ZetCode

Golang package 关键字

最后修改于 2025 年 5 月 7 日

本教程讲解如何在 Go 中使用 package 关键字。我们将通过组织 Go 代码的实际示例来涵盖 package 的基础知识。

package 声明在 Go 中定义了代码模块的命名空间。每个 Go 文件都必须以 package 声明开头。它将相关功能分组。

在 Go 中,packages 是代码组织和重用的主要机制。它们实现了模块化编程并控制包外部标识符的可见性。

基本 package 声明

最简单的 package 声明创建一个可执行程序。main package 在 Go 中是特殊的,因为它定义了一个可执行文件。

basic_package.go
package main

import "fmt"

func main() {
    fmt.Println("Hello from main package")
}

这是可执行 Go 程序的最小 package 声明。当 package 被编译时,main 函数是入口点。

创建 library package

Library packages 提供可重用的功能。此示例展示了一个简单的数学实用程序包。

mathutil/mathutil.go
package mathutil

// Add returns the sum of two integers
func Add(a, b int) int {
    return a + b
}

// Subtract returns the difference of two integers
func Subtract(a, b int) int {
    return a - b
}

package 名称 mathutil 成为导入路径标识符。导出的函数以大写字母开头,使它们可以公开访问。

导入和使用 packages

此示例演示了如何从另一个文件导入和使用我们自定义的 mathutil package。

main.go
package main

import (
    "fmt"
    "./mathutil"
)

func main() {
    sum := mathutil.Add(5, 3)
    diff := mathutil.Subtract(5, 3)
    
    fmt.Printf("Sum: %d, Difference: %d\n", sum, diff)
}

import 语句加载 mathutil package。我们使用 package 名称作为前缀来访问其函数。./ 表示本地 package。

Package 初始化

Packages 可以使用 init 函数具有初始化逻辑。此示例展示了 package 级别的变量和初始化。

config/config.go
package config

import "fmt"

var AppName string
var Version string

func init() {
    AppName = "MyApp"
    Version = "1.0.0"
    fmt.Println("Config package initialized")
}
main.go
package main

import (
    "fmt"
    "./config"
)

func main() {
    fmt.Printf("%s v%s\n", config.AppName, config.Version)
}

当 package 被导入时,init 函数会自动运行。package 中的多个 init 函数按声明顺序执行。

嵌套 package 结构

Go 支持嵌套 package 结构以实现更好的组织。此示例展示了一个嵌套的 package 层级。

mylib/stringutil/reverse.go
package stringutil

// Reverse returns its argument string reversed
func Reverse(s string) string {
    r := []rune(s)
    for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
        r[i], r[j] = r[j], r[i]
    }
    return string(r)
}
main.go
package main

import (
    "fmt"
    "mylib/stringutil"
)

func main() {
    fmt.Println(stringutil.Reverse("Hello, world!"))
}

使用完整路径导入嵌套的 stringutil package。Go 工具在模块系统中自动处理嵌套 package。

内部 packages

Go 的内部 packages 将可见性限制在特定的父 packages。此示例演示了内部 package 机制。

mylib/internal/secret.go
package internal

// SecretKey is only visible to mylib and its subpackages
var SecretKey = "very-secret-key"

// GetKey returns the secret key
func GetKey() string {
    return SecretKey
}
mylib/auth/auth.go
package auth

import "mylib/internal"

func Authenticate() string {
    return internal.GetKey()
}

internal package 只能被 mylib 目录树内的 packages 导入。这为内部实现细节提供了封装。

Package 文档

Go packages 支持内置文档。此示例展示了正确的 package 文档实践。

greeting/greeting.go
// Package greeting provides functions for creating greetings.
// It demonstrates proper Go documentation conventions.
package greeting

import "fmt"

// Greet returns a personalized greeting
func Greet(name string) string {
    return fmt.Sprintf("Hello, %s!", name)
}

// GreetTime returns a greeting with current time
func GreetTime(name string, hour int) string {
    var timeOfDay string
    
    switch {
    case hour < 12:
        timeOfDay = "morning"
    case hour < 18:
        timeOfDay = "afternoon"
    default:
        timeOfDay = "evening"
    }
    
    return fmt.Sprintf("Good %s, %s!", timeOfDay, name)
}

package 注释出现在 package 声明的正上方。函数注释以函数名开头。这些会出现在生成的文档中。

来源

Go 语言规范

本教程通过代码组织和模块化开发的实际示例,讲解了 Go 中的 package 关键字。

作者

我的名字是 Jan Bodnar,我是一名热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1400 多篇文章和 8 本电子书。我在编程教学方面拥有十多年的经验。

列出所有 Golang 教程