import 是告诉 go 编译器使用包的导出符号并执行其 init() 函数,包含标准导入、点导入、别名和下划线四种写法,路径语义指模块坐标而非文件路径。

import 不是“把代码复制进来”,而是告诉 Go 编译器:“我要用这个包的导出符号(函数、类型、变量),并且需要执行它的 init() 函数”。
标准导入、点导入、别名、下划线:四种写法的实际效果
-
import "fmt":最常用。调用时必须加前缀,如fmt.Println() -
import . "fmt":不推荐。省略前缀后,Println("x")可直接调用,但会污染当前命名空间,多人协作时极易引发冲突或隐藏 bug -
import f "fmt":仅在包名冲突时使用,例如同时引入"encoding/json"和第三方"json"包;否则纯属增加认知负担 -
import <em> "net/http/pprof"</em>:只执行init(),不暴露任何符号。典型用于注册 HTTP 路由(pprof)、数据库驱动("github.com/go-sql-driver/mysql")等副作用场景
import (
"database/sql"
_ "github.com/go-sql-driver/mysql" // 注册 mysql 驱动,让 sql.Open("mysql", ...) 可用
)
路径怎么写?GOROOT、GOPATH、Go Modules 三者区别
- 标准库包(如
"fmt"、"net/http")永远用全路径字符串,不加./或../ - 自定义包路径取决于构建模式:
-
Go Modules 开启(推荐):路径就是模块名 + 子目录,如
"myproject/internal/handler",与文件系统物理路径无关 -
GOPATH 模式(已淘汰):路径必须匹配
$GOPATH/src/xxx下的实际目录结构,例如包在$GOPATH/src/github.com/user/util,就得写"github.com/user/util"
-
Go Modules 开启(推荐):路径就是模块名 + 子目录,如
-
./model或../shared这类相对路径导入 仅在极少数临时脚本中可行,项目中禁止使用 —— 它会让go build、go test、IDE 跳转全部失效
为什么 import 后报 “undefined: xxx” 或 “imported and not used”?
常见原因和对应解法:
-
undefined: xxx:- 函数/类型首字母小写(如
func helper()),无法被其他包访问 - 导入路径写错,比如实际模块是
"myorg/core/v2",却写了"myorg/core" - 包名与目录名不一致(如目录叫
utils,但utils.go里写的是package tools)
- 函数/类型首字母小写(如
-
imported and not used:立即学习“go语言免费学习笔记(深入)”;
- 确实没调用该包的任何导出符号 —— 删掉 import 行即可
- 只用了副作用(如驱动注册),但忘了加
_前缀 → 改成import _ "xxx" - 用
goimports替代gofmt,它能自动删未用包、补缺失 import、按组排序
如何组织 import 块才不容易翻车?
Go 官方不强制格式,但工程实践中几乎统一采用三段式分组(空行隔开):
import (
// 标准库(按字母序)
"context"
"fmt"
"time"
<pre class='brush:php;toolbar:false;'>// 第三方模块(按字母序)
"github.com/gorilla/mux"
"golang.org/x/sync/errgroup"
// 当前模块内包(以 go.mod 中 module 名开头)
"myproject/internal/config"
"myproject/pkg/logger")
关键细节:
- 每组内部严格字母顺序,避免 merge 冲突和人工维护成本
- 第三方包路径必须完整,不能简写为
"mux"或"errgroup" - 内部包路径不能以
./开头,也不能漏掉模块前缀(如写成"internal/config"是错的) - 所有
<em></em>导入必须加注释说明目的,例如:// "net/http/pprof" // enable /debug/pprof endpoints
真正容易被忽略的不是语法,而是「路径语义」—— Go 的 import 路径不是文件路径,而是模块坐标。写错一个字符,就等于换了一个宇宙。










