参考书籍:
《深入浅出Go语言核心编程》电子书在线阅读-张朝明;李奕锋;甘海彬-得到APP

这是一本从基础到进阶的 Go 语言学习手册,涵盖语法、内存原理、并发、框架应用等核心内容(比如 Gin 框架),既适合 Go 新手入门,也适合有经验的开发者深入理解底层机制。
Go语言中的main
在 Go 语言中,main 是一个特殊的标识符,主要包含 main 包和main() 函数 两部分,它们共同构成了 Go 可执行程序的入口,是程序运行的起点。
package main
import "fmt"
func main() {
fmt.Println("Hello, Golang!")
}在上面的这段程序中package main 声明的成哥go文件的包名,每个 Go 文件的开头都必须通过 package 包名 声明所属包。一个可执行的 Go 程序必须有且仅有一个main 包,且在该包中必须包含 main() 函数。所以在下面就有了我们看到func main() 。
main() 函数
main() 函数是 Go 程序的入口函数,程序的执行从 main() 函数的第一行开始,到 main() 函数执行完毕结束。
它有这样几个特征:
无参数、无返回值:main() 函数不能定义参数,也不能有返回值,这是语法强制要求。
自动执行:程序启动时,Go 运行时会自动调用 main() 函数,无需手动调用。
唯一存在:在 main 包中,只能有一个main() 函数,多个 main() 函数会导致编译错误。
那当我们需要在执行程序前带参数时要怎么办呢?
启动参数
os.Args 变量
Go语言提供了一个os的包,os.Args 变量来获取命令行参数。
让我们来改一下程序
package main
import (
"fmt"
"os"
)
func main() {
for i, arg := range os.Args {
fmt.Println(i, arg)
}
}这里我们增加了一个 import 的包,然后使用 for 语句循环打印 os.Args 里面的值,看看会有什么效果。
% go run .\first.go a b c
0 ...\go-build\f6\f63846b82478912cbe138a8ba44c2f05d5749664b740d49cf283eeadfd172c8b-d\first
1 a
2 b
3 c当我们执go run .\first.go a b c 的时候,在程序名后面加了三个参数,结果在下方打印出四行文字,第一行是程序编译后所在的临时位置,后面三个就是我们输入的参数了。
但是这种参数的输入方法很不灵活,在需要输入多个参数,且某些参数必填会不必填的时候,程序可能无法分辨用户输入的第几个字符对应第几个参数。
os.flag 函数
os.flag 函数提供了一种更灵活的方法来定义参数,它可以定义参数的名称、默认值等功能。
package main
import (
"flag"
"fmt"
)
func main() {
// 定义命令行参数
name := flag.String("name", "default", "用户名称")
age := flag.Int("age", 18, "用户年龄")
// 解析参数(必须调用,否则参数值为默认值)
flag.Parse()
fmt.Printf("姓名:%s,年龄:%d\n", *name, *age)
}上面的代码定义了 name 和 age 两个参数,并给他们写了默认值。假如我们不输入参数直接执行。
% go run .\get_name.go
姓名:default,年龄:18如果带参数执行。
% go run .\get_name.go -name 李四
姓名:李四,年龄:18
% go run .\get_name.go -name=李四
姓名:李四,年龄:18
% go run .\get_name.go -age=20 -name=李四
姓名:李四,年龄:20我们在输入-name时使用了两种格式,用空格和=连接参数名和值,虽然都能正确识别,但更推荐后者。
同时我们发现,即便输-age=20 -name=李四 这样颠倒位置的参数,也是可以正确识别的。
通过以上两种方式,我们解决了程序运行时初始参数的设置问题。