Day 1|Go 的设计哲学 & 开发环境 [Go 语言 30 天系统学习计划]

今日目标
1️⃣ 建立 正确的 Go 语言心智模型
2️⃣ 搭好标准开发环境
3️⃣ 明白:为什么 Go 代码要“这样写”


一、为什么 Go 语言“看起来简单,却不容易写好”

如果你有 Java / PHP / Python / C++ 经验,第一感觉通常是:

  • 语法很少
  • 没有继承、异常、泛型(旧版本)
  • 很多“高级特性”缺失

但 Go 的核心价值不在语法,而在 工程约束


二、Go 的三大设计哲学(必须记住)

1️⃣ 显式优于隐式(Explicit is better than implicit)

体现在哪里?

  • 错误是返回值,不是异常
  • 没有隐式类型转换
  • 没有默认参数
  • 接口是显式方法集合

示例:错误处理是显式的

v, err := strconv.Atoi("123")
if err != nil {
    // 必须显式处理
    fmt.Println(err)
}

过程说明

  • err 是普通返回值
  • 不处理就会被你“看到”

结论

Go 不替你“兜底”,但保证你“看得到风险”


2️⃣ 组合优于继承(Composition over inheritance)

Go 没有继承,但有两种组合方式:

  • struct 嵌入
  • interface 组合

示例:struct 嵌入

type Logger struct{}

func (l *Logger) Log(msg string) {
    fmt.Println("log:", msg)
}

type Service struct {
    Logger
}
func main() {
    s := Service{}
    s.Log("hello")
}

过程说明

  • Service 没有继承 Logger
  • 只是“拥有”一个 Logger 的能力

结论

Go 组合的是“能力”,不是“血缘关系”


3️⃣ 简单优于聪明(Simplicity over cleverness)

Go 追求:

  • 易读
  • 易维护
  • 易协作

不追求:

  • 炫技
  • 极致抽象
  • DSL 风格代码

示例:for 是唯一循环

for i := 0; i < 3; i++ {
    fmt.Println(i)
}

没有:

  • while
  • do-while
  • foreach(语法级)

结论

Go 把复杂度留给架构,不留给语法


三、Go 的执行模型(先有整体感)

Go 程序从 main 包的 main 函数开始执行。

package main

func main() {
    // 程序入口
}

必须遵守的规则

  • 每个可执行程序 只能有一个 main 包
  • main 包中 必须有 main()

四、Go 开发环境搭建(标准做法)

1️⃣ 安装 Go(略)

验证:

go version

2️⃣ Go Module(非常重要)

Go 现在 强制使用 module,不再依赖 GOPATH。

初始化一个项目

mkdir hello-go
cd hello-go
go mod init hello-go

生成:

go.mod

3️⃣ 第一个 Go 程序

// main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, Go")
}

运行:

go run main.go

结果

Hello, Go

五、Go 的基础工具链(每天都会用)

1️⃣ go run

  • 编译 + 运行
  • 适合开发期
go run main.go

2️⃣ go build

  • 只编译,生成二进制
go build

结果:

./hello-go

3️⃣ go fmt(强制风格)

go fmt ./...

重要认知

Go 代码风格不是“建议”,而是“强制”


4️⃣ go vet(静态检查)

go vet ./...

六、package 与 import 的基本规则

1️⃣ package 是编译单元

package main
  • 同目录下文件必须同 package
  • package 名不一定等于目录名(但强烈建议一致)

2️⃣ import 规则

import (
    "fmt"
    "time"
)
  • 未使用的 import 会 直接编译失败
  • 这是 Go 的刻意设计

七、你今天必须理解的 5 个关键点

  1. Go 是 工程语言,不是学术语言
  2. 显式错误是优点,不是缺点
  3. 没有继承 ≠ 表达能力弱
  4. 工具链是语言的一部分
  5. 写 Go 是在为“未来的维护者”负责

八、Day 1 实践任务(必须做)

任务 1:初始化项目

mkdir go-study
cd go-study
go mod init go-study

任务 2:写一个最小程序

要求:

  • 使用 fmt
  • 至少一个函数
package main

import "fmt"

func hello(name string) {
    fmt.Println("hello", name)
}

func main() {
    hello("Go")
}

运行结果

hello Go

任务 3:故意犯错并修复

1️⃣ 删除 fmt 的使用
2️⃣ 运行 go build
3️⃣ 阅读错误信息并修复


九、自检清单(非常重要)

在进入 Day 2 前,你应该能回答:

  • Go 为什么不用异常?
  • package 的边界是什么?
  • go fmt 为什么是强制的?
  • Go 的“简单”体现在哪里?

如果有任何一个答不上来,不要急着往后学


预告:Day 2 学什么

Day 2|变量、控制流与值语义

你将彻底搞清楚:

  • Go 为什么“到处拷贝”
  • 为什么新手 Go 代码容易写 Bug
  • defer 的真正执行顺序
  • for + goroutine 的经典坑

发表评论