本文是《100天精通Go基础入门》专栏第 01 篇,订阅专栏不迷路。
本文目录
-
今日目标
-
概念图解
-
跟做案例
-
新手常见的坑
-
课后小任务
-
明日预告

今日目标
今天结束时你手里会有两样东西:一个能用的 go 命令,和一个你自己写、自己编译出来的 .exe。后者可以直接拷到任何一台 Windows 电脑上双击运行,那台机器不用装 Go,也不用装任何运行时。
这一百天的路也顺便交代清楚:Day 100 那天,你要独立做出一个能公网访问的 Go 后端服务。
概念图解
先解开一个新手心结:为什么学别的语言第一步是"装运行时",而 Go 的最后一步却是"删掉依赖"。
把写程序理解成给别人做一道菜。Python 和 Java 交出的是一份菜谱 :代码发给朋友,朋友得先把厨房搭起来,装解释器、装依赖、对齐版本,差一点就跑不起来,你在群里发一句 pip install -r requirements.txt,对方大概率回你一张报错截图。
Go 交出的是一份做好的盒饭:编译时它把运行时代码、垃圾回收、协程调度器统统塞进一个可执行文件。这个文件是静态的,不依赖对方电脑上有没有 Go。

再分清两个命令,这是你这两天最容易被绕晕的地方。go run 是"替你试个味道",编译、运行、然后把产物偷偷删掉 ;go build 是"正式出餐",exe 留在你眼前。

跟做案例
顺序是:装 Go → 确认命令行认识它 → 写最小程序跑通 → 再写今天真正的成果。
去 Go 官网下载页拿 Windows 的 zip 包,解压到 D:\go,把 D:\go\bin 加进系统 Path。用 zip 不用 .msi,是因为 .msi 会往 C 盘塞东西、还会改全局环境变量,攥在自己手里更省心。配完 Path 必须关掉所有终端重开一个,环境变量只在进程启动时读一次,老窗口不知道新加的路径。然后敲三行
go version
go env GOROOT
go env GOPROXY

看到 go version go1.27.0 windows/amd64,环境就立住了。第三条 GOPROXY 先留个印象,后面要下第三方库而下不动时,改的就是它。
接着在 D:\go\day01 里新建 main.go,写六行:
// 《100天精通Go基础入门》Day 01 · 平头哥 · 技术改变世界,勤奋改变人生
package main
import "fmt"
func main() {
fmt.Println("你好,Go")
}


执行 go run main.go,打出"你好,Go"就成功了。这六行里有三样你以后天天见:package main 声明"这是一个能独立运行的程序",import "fmt" 引进格式化输出的能力,func main 是唯一入口。Go 不像有些语言给你一堆入口,它只认这一个。
然后是今天的实战产出。光打印一句话太单薄,我们写一份环境体检报告:让 Go 自己去问操作系统"我是谁、跑在什么机器上、坐在哪个目录"。这段稍长,现在不用每个函数都看懂,照抄、跑通、看到输出就是胜利。
// 《100天精通Go基础入门》Day 01 · 平头哥 · 技术改变世界,勤奋改变人生
package main
import (
"fmt"
"os"
"runtime"
"strings"
)
func main() {
fmt.Println("=== 我的 Go 环境体检报告 ===")
fmt.Println("Go 版本 :", runtime.Version())
fmt.Println("操作系统 :", runtime.GOOS)
fmt.Println("CPU 架构 :", runtime.GOARCH)
fmt.Println("编译器 :", runtime.Compiler)
fmt.Println("逻辑核心 :", runtime.NumCPU(), "个")
line := strings.Repeat("-", 44)
fmt.Println(line)
wd, _ := os.Getwd()
fmt.Println("工作目录 :", wd)
exe, _ := os.Executable()
fmt.Println("真正在跑 :", exe)
fmt.Println(line)
// 100 天进度条:20 个格,每格代表 5 天
day := 1
total := 100
filled := day * 20 / total
if filled == 0 {
filled = 1
}
fmt.Print("专栏进度 : ")
for i := 1; i <= 20; i++ {
if i <= filled {
fmt.Print("#")
} else {
fmt.Print(".")
}
}
fmt.Printf(" Day %d/%d,还剩 %d 天\n", day, total, total-day)
fmt.Println(line)
fmt.Println("能把这张表跑出来,你的 Go 环境就算装利索了。")
}


讲两件你一定会问的。
wd, _ := os.Getwd() 里那个下划线。Go 的函数经常一次回你两个值:结果和错误。Go 不允许你假装没看见那个错误 ,但今天你确定不会出错,就用 _ 明明白白扔掉它。这不是敷衍,是一句写给同事看的声明:"我知道这里有个错误,我今天不管"。
再看输出里"真正在跑"那行,路径藏在一串随机数字里,不在你的 D:\go\day01。我这台机器把编译缓存指到了 D:\go\.cache,你的机器上默认会在 C:\Users\你的用户名\AppData\Local\go-build 或 Temp 下面------位置不同,但结论一样:它不在你的项目文件夹里 。这就是前面说的:go run 编译到临时目录、跑完就丢。你要是敲完 go run 就去文件夹翻 exe,是翻不到的。想让它在,补一句:
go build -o myapp.exe main.go
powershell -NoProfile -Command "Get-ChildItem myapp.exe | Format-Table Name,Length"

跑完再看文件夹,myapp.exe 躺在那儿了,实测 2.4 MB,里面装着一个完整的 Go 运行时。把它单独发给朋友,他双击就能看到那句"你好,Go"。我是平头哥,技术改变世界,勤奋改变人生,咱们接着往下写。
新手常见的坑
Go 编译器的严格程度是第一天头号劝退点。它会因为你不用了一个变量而拒绝编译,而不是警告一句就放行。我带过转语言的同学,第一天几乎人人在这两处撞墙,而且撞完都觉得自己写对了。
第一个坑,fmt 用得挺顺但忘了 import,现象是一句冷冰冰的 undefined: fmt,连行号都给你指到。
// 《100天精通Go基础入门》Day 01 · 平头哥
package main
func main() {
fmt.Println("你好,Go")
}

第二个坑是今天的主角:定义了变量却没用。你想着先声明一个 name 待会儿用,结果忘了用,Go 直接不给编译。
// 《100天精通Go基础入门》Day 01 · 平头哥
package main
import "fmt"
func main() {
fmt.Println("你好,Go")
name := "平头哥"
}

正确写法要么删掉它,要么当场用上。这条规矩看着不近人情,但它替你挡住了更可怕的事故:一个变量被改了名字、逻辑被挪走了,却还留在原地,你后来读到它以为它有用。Go 选择让这种代码根本编译不出来,而不是等线上出怪问题再查。
第三个坑用嘴说一下,因为它明天还会来烦你:配完 Path 后老终端里 go 仍提示"不是内部或外部命令"。这不是没配对,是那个窗口还带着启动时的旧记忆,关掉重开就好。
课后小任务
把体检报告最后那句提示改成你自己的名字和今天的日期;再把 day := 1 改成 day := 37,看进度条变成什么样,然后改回来。最后执行 go build -o 我的报告.exe main.go,把生成的 exe 拷到桌面双击一次。
参考资料
投票:Go 强制"变量声明了就必须使用",你的第一反应是?选项:早该这样 / 太死板了
我是平头哥,技术改变世界,勤奋改变人生。 《100天精通Go基础入门》每天更新,订阅专栏不迷路。