Go中的包是组织代码和管理可见性的主要构建块。Go历史上选择了一种简单的导入和文件夹层次结构模型,以使编程透明,并避免像C/C++和Java中依赖解析的不确定性。Go解决的问题是创建明确的项目结构,防止名称冲突以及模块之间的独立性。
问题:没有统一的组织方法,无法扩展应用程序,会出现重复、名称冲突和循环依赖。重要的是要明确关注对象的可见性。
解决方案:每个目录包含一个包文件(package somepackage),目录名和包名一致是最佳实践。通过关键字import进行导入,只有首字母大写的对象才会被导出。依赖管理通过go modules(go.mod)进行。
结构和导入示例:
// internal/mathops/add.go package mathops func Add(a, b int) int { return a + b } // main.go package main import ( "fmt" "myservice/internal/mathops" ) func main() { fmt.Println(mathops.Add(2, 3)) }
关键特性:
在同一目录中可以声明多个不同的包吗?
不可以,目录中的所有文件必须属于同一包。
如果函数名首字母大写,而包名首字母小写,函数会变为可导出吗?
会的,导出只取决于对象名称的首字母(函数、类型、变量),而与包名无关。
可以用不同的别名导入包吗,这会影响函数的可见性吗?
可以。别名仅影响如何引用包的名称,但不改变可见性:
import mymath "myservice/internal/mathops" mymath.Add(1,2)
开发者将所有函数放在一个名为"utils.go"的文件中,位于main包中,没有将业务逻辑分隔到单独的包中。
优点:
缺点:
业务逻辑、工具、处理器和数据模型被分离到独立的包中:mathops、user、storage、api。严格按需导入,每个包单独测试。
优点:
缺点: