

新闻资讯
技术学院Go程序入口func main()必须位于package main中,签名固定为无参数无返回值,且一个目录下只能有一个;使用flag包解析命令行参数需调用flag.Parse(),支持--name=Tom等格式,不支持位置参数。
Go 程序入口是 func main(),它只能出现在 package main 中。如果写成其他包名(比如 package cmd),go run 会报错:cannot run non-main package。这不是语法错误,而是构建约束——Go 编译器直接拒绝执行。
实操建议:
package main
main 函数不能带参数、不能有返回值(签名固定为 func main())package main,否则 go run . 会报 multiple main packages
Go 标准库的 flag 包足够应付“最简单”的需求,比如接收一个字符串或整数参数,不需要第三方依赖。
常见错误现象:直接用 os.Args 手动解析,结果漏掉 Args[0] 是程序名,或没处理空参数、类型转换失败等边界情况。
立即学习“go语言免费学习笔记(深入)”;
实操建议:
flag.String / flag.Int 声明参数,自动处理默认值、类型转换和帮助信息flag.Parse()
才能触发解析,否则所有 flag.Xxx 返回零值-h / --help)是内置的,不用额外写逻辑package main
import (
"flag"
"fmt"
)
func main() {
name := flag.String("name", "World", "your name")
flag.Parse()
fmt.Printf("Hello, %s!\n", *name)
}
Go 编译出的二进制不支持 ./cmd --name=Tom 和 ./cmd --name Tom 混用——flag 包对等号格式敏感,且只认 --xxx 或 -x 形式,不接受 ./cmd Tom 这种无 flag 名的位置参数(除非显式用 flag.Args())。
使用场景:调试阶段常用 go run . --name=Alice;发布时用 go build -o hello && ./hello --name=Bob。
容易踩的坑:
--name=Tom ✅,--name= Tom ❌(等号后有空格会导致值为空)-name Alice ❌(name 不是单字母,不能用短格式),应写 --name Alice
./hello --name Tom extra 中 extra 会进入 flag.Args(),但 --name 仍能正确解析如果你删掉了 func main(),或者把它改名叫 func Main(),go run . 不会报错,而是直接退出,什么也不输出——这是 Go 工具链的设计:找不到 main 就当“没可运行内容”,而非报错。
这比编译失败更难排查,尤其对新手。验证方式只有两个:
package main
func main(),且签名完全匹配(无参数、无返回值)复杂点在于:如果项目里混了测试文件(xxx_test.go)或工具文件(比如生成代码用的 gen.go),它们也可能声明 package main,导致 go run . 模糊匹配到错误文件。此时应明确指定文件:go run main.go。