Skip to content

3.2 包与导入

写好 import,程序才能用到标准库、本模块其它包以及第三方模块。依赖从哪来、版本谁管3.1 Go mod 模块管理 负责;本节聚焦:导入语法、包名与路径的关系、初始化顺序、模块模式下的解析习惯

一、包与导入路径

  • 包(package):同一目录下的 .go 文件,首行用同一个 package xxx 声明;编译单元以目录为单位。
  • 导入路径(import path)import "..." 里的字符串。在 Go Modules 下,一般是 模块路径 + 子目录(如 github.com/gin-gonic/gin),标准库则短路径(如 fmt)。
  • 包名与目录名:习惯上目录名与 package 名一致,但可以不同。例如目录名叫 utilset,文件里却是 package utils,则 import 仍写模块下的路径,调用时要用 utils.导出名,而不是目录名 utilset
go
import "example.com/myapp/utilset" // 导入路径对应目录 utilset

func f() {
	utils.SomeFunc() // ✅ 与 package 声明一致
	// utilset.SomeFunc() // ❌ 包名不是 utilset 时无法编译
}

读别人代码时以各文件顶部的 package为准。

二、单行导入与分组导入

路径必须用双引号。多包时用分组形式更清晰(gofmt 会整理顺序):

go
import "fmt"

import (
	"fmt"
	"sync"
)

三、别名导入

用于避免包名冲突缩短长路径与本地变量名冲突

go
import (
	"crypto/rand"
	mrand "math/rand"
)

import pathpkg "path"

四、点导入(.

go
import . "fmt"

func main() {
	Println("hello") // 等价于 fmt.Println,但不写包名
}

会把被导入包的导出符号放进当前文件作用域,易与本地标识符冲突,可读性也差。除极小示例外不推荐

五、匿名导入(空白导入 _

只执行包的 init 副作用(如注册数据库驱动、编解码器),不在代码里直接引用包名:

go
import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
)

编译器要求 import 被使用_ 表示「仅为副作用导入」。

六、init 与包初始化顺序

1. init 的特点

  • 签名固定为 func init(),无参数、无返回值。
  • 不能被业务代码调用。
  • 同一包、同一文件可写多个 init,按源文件名字典序文件内自上而下依次执行(以当前 Go 语言规范为准)。
  • init 之前,会先完成包级常量、变量的初始化(依赖解析顺序由声明与初始化表达式决定)。

2. 跨包顺序(依赖图)

main → A → Bmain import A,A import B),则先完成 B 的包级变量与 init,再 A,最后 main 的包级变量与 init,最后 main.main。概括为:被依赖方先于依赖方初始化

3. 小示例

go
package main

import "fmt"

func init() { fmt.Println("init1:", a) }
func init() { fmt.Println("init2:", a) }

var a = 10

func main() { fmt.Println("main:", a) }

典型输出中,两个 inita 已为 10,随后进入 main

七、模块模式下的路径解析

日常在 3.1 已用 go mod init 的项目里,应使用 import 的模块路径不要使用相对路径(如 ./foo):Go Modules 不支持这类相对导入作为常规做法。

解析依赖时(简化理解):

  1. 标准库(如 fmt):来自 GOROOT
  2. 若使用 -mod=vendor 且存在 vendor/:优先从 vendor 解析(与 3.1 中 go mod vendor 配套)。
  3. 其它模块:来自模块缓存(通常 $GOPATH/pkg/mod 或等价位置),版本由 go.mod 锁定。

旧式 仅 GOPATHgovendor 的搜索优先级只需做背景了解;新项目以 模块 + go.mod 为准即可。

八、小结

要点说明
路径 vs 包名import 用路径;代码里用 package 声明的名字 访问导出符号。
导入形式普通、别名.(慎用)、_ 副作用导入
init自动执行,注意跨包依赖顺序与包级变量初始化先后。
模块项目相对路径 import 避免使用;依赖版本交给 3.1 Go mod

更多官方说明可在终端执行 go help importpathgo help modules 查阅。