假设我们有一个名为utils的包,包含两个文件:math.gostring.go,都属于utils包。

1. 文件 1:utils/math.go(定义函数)

package utils

// 非导出函数(首字母小写):仅包内可见
func add(a, b int) int {
    return a + b
}

// 导出函数(首字母大写):包内外均可调用
func Multiply(a, b int) int {
    return a * b
}

2. 文件 2:utils/string.go(调用 math.go 中的函数)

package utils

import "fmt"

// 调用同包不同文件的add(非导出)和Multiply(导出)函数
func CalculateAndPrint(x, y int) {
    sum := add(x, y) // 直接调用math.go中的非导出函数
    product := Multiply(x, y) // 直接调用math.go中的导出函数
    fmt.Printf("Sum: %d, Product: %d\n", sum, product)
}

3. 主文件:main.go(导入 utils 包,调用导出函数)

package main

import "your-module-path/utils" // 替换为实际模块路径

func main() {
    // 调用utils包的导出函数CalculateAndPrint(内部已调用同包其他文件的函数)
    utils.CalculateAndPrint(3, 5)
    
    // 直接调用utils包的导出函数Multiply
    fmt.Println("Multiply:", utils.Multiply(2, 4))
    
    // 错误:无法调用非导出函数add(包外不可见)
    // utils.add(1,2) // 编译报错:undefined: utils.add
}

注意事项

  1. 包名必须一致:同一个包下的所有文件,第一行的package 包名必须完全相同(比如都写package utils,不能一个写utils一个写util);
  2. 编译时需包含所有文件:
  • go run运行时,若主文件依赖同包其他文件,需显式指定所有文件(或用通配符): 
# 方式1:指定所有文件
go run main.go utils/math.go utils/string.go
# 方式2:用通配符(推荐,自动包含同目录下的所有go文件)
go run ./...
  • go build编译时,会自动包含同一个包下的所有文件,无需额外指定;

    3.避免循环依赖:同一个包下的文件之间可以相互调用,但不能出现循环依赖(比如 A 文件调用 B 文件的函数,B 文件又调用 A 文件的函数,这在 Go 中是允许的,但需注意逻辑合理性)。

  

总结

  1. 同一个包名下不同文件的函数可以直接调用,非导出函数(小写开头)仅限包内调用,导出函数(大写开头)包内外均可调用;
  2. 关键前提是:所有文件的包名一致,且编译时包含所有相关文件;
  3. 这是 Go 包机制的核心特性,目的是让同一个功能模块的代码可以拆分到多个文件中,保持结构清晰

 

 

 

 

 posted on 2025-11-26 15:48  boye169  阅读(14)  评论(0)    收藏  举报