前置知识: 计算机基础

Go 是什么:为大规模工程而生的简洁语言

7 min入门

面向零基础读者介绍 Go 的定位、设计哲学、并发优势与工程哲学,完成第一个程序的编写、运行与格式化。

前置知识

  • 编程基础:只要写过任何一门语言的 Hello World,或理解”变量、函数、循环”这三个词,就可以开始本篇。

学习目标

  1. 说清 Go 的定位:它解决什么问题,不解决什么问题。
  2. 理解 Go 的三条设计哲学:语法极小、并发内建、部署极简。
  3. 独立完成第一个 Go 程序的编写、运行、编译与格式化。
  4. 直观感受 goroutine 并发,为后续 channel 与调度模型的学习建立锚点。

Go 在技术版图中的位置

Go(又名 Golang,因早期域名 golang.org 而得名,正式名字就是 Go)由 Google 的 Robert Griesemer、Rob Pike 与 Ken Thompson 于 2007 年立项、2009 年开源发布,专为大规模服务端工程设计。今天的基础设施半壁江山由 Go 编写:Docker、Kubernetes、etcd、Prometheus——云原生时代的地基几乎都是 Go。

方向代表产物
云原生与容器Docker、Kubernetes、containerd
后端接口服务各类高并发 API 服务、微服务
命令行工具单文件分发、跨平台编译(如 hugo、traefik)
中间件与存储etcd、CockroachDB、MinIO
开发工具链gopls、 gofmt,以及大量 DevOps CLI

Go 采用一年两个大版本(2 月与 8 月)的固定节奏,每个大版本持续获得约两年的安全修复。语言本身极其稳定:Go 1 兼容性承诺保证十年前编译通过的规范代码,今天的工具链仍能构建运行。

三条设计哲学

语法极小:Go 的关键词只有 25 个(Java 是 50+),官方语言规范一个下午能读完。这是刻意为之的设计哲学——一门语言只提供一种写法,团队里一万个人写出的代码像一个模子。 没有三元运算符、没有隐式类型转换、没有未使用变量的容忍:编译器把”代码风格”之争从团队里彻底拿走了。

并发开箱即用:一行 go 函数名() 就能启动一个轻量并发任务(goroutine),初始栈仅 2KB,单进程轻松承载成千上万并发,由运行时调度到少数操作系统线程上。配合 channel(通道)实现”以通信共享内存”,这是”高并发后端”教学总用它举例的原因。

编译产物单文件:go build 产出一个静态链接的可执行文件,丢到服务器就能跑,不需要安装运行时或依赖库——部署体验碾压需要虚拟机的路线。交叉编译也是一句话的事:GOOS=linux GOARCH=amd64 go build 即可在 Mac 上构建 Linux 二进制。

此外还有一条容易被忽略的底线:垃圾回收内建,且以低停顿(亚毫秒级)为设计目标,不需要手动管理内存,也不像某些语言那样需要调一堆 JVM 式参数。

Go 擅长与不擅长的事

选型前先看清边界,比记住优点更重要。

场景适合度原因
高并发网络服务、API 网关很适合goroutine + netpoller,C10K 问题不存在
CLI 工具、DevOps 程序很适合单文件交叉编译,启动零开销
云原生基础设施很适合Kubernetes 生态事实标准
数据处理管道、爬虫适合并发模型天然契合
GUI 桌面应用不适合生态薄弱,非设计目标
科学计算、深度学习不适合生态在 Python 侧,泛型表达能力有限

第一行代码

安装 Go 后(见 Go 概述与环境配置),新建 hello.go:

package main // 可执行程序必须声明 main 包

import "fmt" // 引入格式化输出包,Go 惯例:包名简短、全小写

// main 函数是程序入口:无参数、无返回值
func main() {
    fmt.Println("你好,Go")
}

终端执行:

go run hello.go    # 编译到临时目录并直接运行
# 输出:
# 你好,Go

go build hello.go  # 产出可执行文件 hello.exe(Windows)或 hello(Linux/Mac)
./hello            # 运行编译产物,输出与 go run 相同

逐行看:package main 声明主包,main 包 + main 函数是可执行程序的唯一入口约定;import "fmt" 引入标准库的格式化包;函数体只有一行。没有任何分号(编译器自动插入)、没有类包装、没有多余的样板——这就是 Go 的气质。

再体验两件 Go 工程师每天都要做的事。第一是格式化不是喜好,是命令:

gofmt -w hello.go  # 官方格式化工具,全社区唯一的代码风格

第二是未使用的变量是编译错误。试着在 main 里加一行 x := 1 但不使用它,go run 会直接拒绝编译:

# 命令行-参数
./hello.go:7:5: x declared and not used

这类”啰嗦的严格”贯穿 Go 全程:它宁可编译时报错,也不把问题留给运行时。

动手环节:感受并发

把 main 函数换成下面这样,用三行代码把任务变成并发执行:

package main

import (
    "fmt"
    "time"
)

func main() {
    for i := 1; i <= 3; i++ {
        go fmt.Println("并发任务", i) // go 关键字:启动一个 goroutine
    }
    time.Sleep(100 * time.Millisecond) // 等待一下,防止 main 结束时 goroutine 还没跑
}

一次可能的输出:

并发任务 3
并发任务 1
并发任务 2

两个观察点值得留意:

  1. 三个任务都打印出来了,但顺序不确定——goroutine 是并发调度的,输出交错与乱序正是并发的常态。依赖执行顺序的并发代码必须用同步原语(channel、WaitGroup)协调,这是本模块并发章节的主题。
  2. 循环变量 i 直接在 goroutine 里使用是安全的:Go 1.22 起每次迭代都会创建新变量,旧版本”所有 goroutine 共享同一个 i”的经典陷阱已被语言层面修复(详见 Go 新特性演进)。

go 一个关键字就把循环体变成并发执行——在其他语言里这需要线程池或复杂框架。生产代码里等待并发任务完成不会用 time.Sleep,而会用 sync.WaitGroup 或 channel,先建立直观即可。

再看一眼:错误处理的样子

Go 没有 try/catch。错误是普通的返回值,用 if err != nil 逐层处理:

package main

import (
    "fmt"
    "os"
)

func main() {
    data, err := os.ReadFile("config.yaml")
    if err != nil {
        fmt.Println("读取配置失败:", err) // 错误就在发生的那一行被处理
        return
    }
    fmt.Println("配置内容字节数:", len(data))
}
# 文件不存在时的输出:
读取配置失败: open config.yaml: no such file or directory

初学者常觉得 if err != nil 啰嗦,它的回报是:每一处可能出错的地方,代码里都有一处显式的处理,控制流没有隐藏的跳跃。本模块的错误处理篇(Go 错误处理)会展开这套体系的完整用法。

常见困惑

“Go 没有类和继承?“——它刻意不提供类继承,用”结构体 + 接口 + 组合”达到同等表达力,且避免深层继承带来的维护灾难。面向对象思想依然适用,只是形态不同(见 Go 接口与组合)。

“为什么不用 try/catch?“——Go 团队认为异常会把错误处理从调用点挪走,制造”看起来安全实则裸奔”的代码。Go 用 error 返回值覆盖 99% 的失败场景,用 panic/recover 兜底真正的程序性缺陷,两级机制各司其职。

“与 Java 怎么选?“——重业务逻辑、生态沉淀选 Java;重并发、云原生、部署简洁选 Go。本仓库两者都有完整模块,语法基础互通。

“与 Python 怎么选?“——脚本、数据探索、AI 生态选 Python;需要并发、低资源占用、单文件分发的服务端程序选 Go。Go 的编译期类型检查也让大团队协作的重构成本显著低于动态类型。

本篇小结

  1. Go 是为大规模服务端工程设计的静态编译语言,云原生基础设施的事实标准。
  2. 三条设计哲学:语法极小(25 个关键词)、并发内建(goroutine + channel)、部署极简(单文件交叉编译)。
  3. go run 直接运行、go build 产出可执行文件、gofmt 统一风格;未使用变量是编译错误。
  4. go 关键字一行启动并发任务;并发输出天然乱序,同步机制后续章节展开。
  5. 错误是普通返回值,if err != nil 让每处失败都有显式处理点。

下一步

进入 Go 概述与环境配置 安装工具链并理解 GOPATH 到 Modules 的演变;本模块的学习主线是:语法(003-005)→ 接口与并发(006-007)→ 错误处理(008-009)→ 泛型与工程化(010-011),随后可按兴趣深入原理篇与生态篇。学到并发与接口时,建议回头重读本篇的两个动手环节。