Golang中_internal包应该存放哪些内容?
Golang中_internal包应该存放哪些内容? 大家好,
你们通常在 /internal 目录中存放什么内容?是存放验证辅助函数,还是数据库模型?
这与 DDD 范式有何关联?你们会将领域逻辑存放在 /internal 包中吗?
2 回复
你好 @heidi,
/internal 目录被 Go 编译器识别为一个特殊目录。/internal 内部的包无法被其他项目访问。
通过将包放入 /internal,你可以减少你的公共 API 表面积。
关键在于,如果你的项目是公开的,迟早会有其他人开始使用你项目的公共包,无论你是否打算让所有这些包都被他人复用。这会增加维护负担,并降低你随意更改包 API 的能力。
因此,如果你有一些不希望为他人维护、并且其包 API 很可能发生变化的包,请将它们放入 /internal。
(更多关于 Go 项目布局的信息在此。)
更多关于Golang中_internal包应该存放哪些内容?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
在Go项目中,/internal目录用于存放不对外公开的代码,这些代码只能被项目内部的包导入,外部项目无法引用。根据Go 1.4引入的internal机制,其设计目的是保护项目内部实现细节,避免外部依赖。
典型存放内容:
- 项目私有工具函数(如验证辅助函数、字符串处理等)
- 数据库模型和仓储实现(如果采用DDD,通常存放仓储的具体实现)
- 服务层实现细节
- 中间件实现
- 配置加载逻辑
- 领域逻辑的具体实现(在DDD中,领域实体的行为实现)
与DDD的关联:
在DDD架构中:
/internal通常存放领域逻辑的具体实现、基础设施层代码(如数据库操作)和应用服务实现- 领域模型的核心接口(如仓储接口、领域服务接口)通常放在项目根目录或
/pkg中对外公开 - 领域实体本身通常放在
/internal中保护其内部状态和行为
示例代码结构:
// 项目结构示例:
myapp/
├── cmd/
│ └── server/
│ └── main.go
├── internal/
│ ├── user/
│ │ ├── repository/ # 仓储实现
│ │ │ └── mysql.go # MySQL具体实现
│ │ ├── service/ # 应用服务实现
│ │ │ └── service.go
│ │ └── validator/ # 验证辅助函数
│ │ └── validator.go
│ └── pkg/
│ └── crypto/ # 内部加密工具
│ └── aes.go
├── pkg/
│ └── user/ # 对外公开的包
│ ├── repository.go # 仓储接口
│ └── entity.go # 实体接口
└── go.mod
// internal/user/validator/validator.go
package validator
import "regexp"
// 内部验证函数,外部无法导入
func ValidateEmail(email string) bool {
re := regexp.MustCompile(`^[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}$`)
return re.MatchString(email)
}
// internal/user/repository/mysql.go
package repository
import (
"database/sql"
"myapp/pkg/user" // 只能导入项目内部的公开包
)
type userRepository struct {
db *sql.DB
}
// 实现pkg/user中的Repository接口
func (r *userRepository) FindByID(id int) (*user.Entity, error) {
// 具体数据库查询实现
return &user.Entity{ID: id}, nil
}
关键原则:
- 如果代码需要被其他项目导入使用,应该放在
/pkg目录 - 如果代码是项目内部实现细节,应该放在
/internal - 在DDD中,领域实体的核心行为(方法)可以放在
/internal中实现,但接口定义通常对外公开 - 数据库模型如果包含业务逻辑,适合放在
/internal;如果是简单的DTO,可以考虑放在/pkg
这种结构确保了项目的封装性,同时支持清晰的架构分层。

