Day 01 | go run 跑通第一个 Go 程序,go build 留下一个能拷走的 exe

本文是《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基础入门》每天更新,订阅专栏不迷路。

相关推荐
葡萄城技术团队1 小时前
工业数据可视化:使用活字格 AIcoding + Three.js 构建轻量化三维设备监控大屏
开发语言·javascript·信息可视化
qiaosaifei1 小时前
JAVA老项目中有大量的类名_编译时报找不到符号错误
java·开发语言
聪明蛋子哟1 小时前
MCP协议深度落地:如何用Python/Java双语言实现统一的工具调用网关?
java·开发语言·python
2601_962296512 小时前
如何使用Golang包路径_管理本地和远程模块引用
golang·数据转换·变量定义·常用库·编程语言区别
一晌小贪欢2 小时前
python-第27天:Python面向对象详解
开发语言·python·数据可视化·面向对象·python办公
ZGG0032 小时前
线程池详解:从 7 大参数到生产避坑
java·数据库·后端
迪康Defender2 小时前
公用电脑责任追溯难?迪康端点安全一体化管理系统用户模式详解
java·运维·开发语言·网络·其他·安全
16月6日-晴3 小时前
Java面向对象——接口
java·开发语言
wuyk5553 小时前
107.FreeRTOS 链表深度解析:从原理到面试满分答案
c语言·开发语言·数据结构·stm32·单片机·链表·面试