Go程序入口func main()必须位于package main中,签名固定为无参数无返回值,且一个目录下只能有一个;使用flag包解析命令行参数需调用flag.Parse(),支持--name=Tom等格式,不支持位置参数。

main 函数必须在 package main 里
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
用 flag 包读取最简命令行参数
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 - 参数顺序:flag 必须在非 flag 参数之前,
./hello --name Tom extra中extra会进入flag.Args(),但--name仍能正确解析
没有 main 函数时 go run 会静默失败
如果你删掉了 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。









