Go 语言入门:十问十答
这是「Golang学习」模块的第一篇。用问答的方式记录我和 AI 学习 Go 的过程——有踩坑记录、有顿悟时刻、也有经验总结。
Q1:Go 到底是什么?为什么又要学一门语言?
A: Go(Golang)是 Google 在 2009 年发布的开源编程语言。核心卖点就三个:
| 特性 | 说明 |
|---|---|
| 编译快 | 大项目秒级编译,不像 C++ 那样喝杯咖啡回来还在编 |
| 并发原生 | go 关键字 + channel,协程比线程轻量几个数量级 |
| 部署简单 | 编译出一个二进制文件,扔上去就能跑,无运行时依赖 |
你已经有 Java/Python/Go 的经验,Go 最适合的场景是:网络服务、微后端、CLI 工具、云基础设施。你的 slg-go 项目就是典型用例。
Q2:Hello World 长什么样?
1 | package main |
几点说明:
package main— 每个 Go 程序必须有且只有一个main包func main()— 程序入口,没有参数、没有返回值(和 C/Java 不同)import— 只引用用到的包,Go 不允许 import 了不用的包(编译直接报错)- 分号 — 不需要写,编译器自动插入
Q3:变量声明有几种写法?
A: 四种,从啰嗦到简洁:
1 | // 方式一:完整声明(最啰嗦) |
实战建议:函数内部用 :=,包级别用 var。别纠结,肌肉记忆两天就有了。
Q4:Go 的类型系统有什么特别的?
A: 几个关键点:
没有隐式类型转换
1 | var x int32 = 42 |
这对 Java 开发者来说一开始很烦,但能避免一堆隐蔽的 bug。
有指针但没有指针运算
1 | x := 42 |
比 C 安全,比 Java 更灵活。恰到好处。
有 string 但注意它是不可变的
1 | s := "hello" |
Q5:数组和切片(Slice)什么区别?这个坑我踩过!
A: 这是新手第一坑:
1 | // 数组:固定长度,值类型 |
口诀:日常开发 99% 用切片,数组几乎只在底层优化时碰到。
Q6:Map 怎么用?
1 | // 创建 |
注意那个 ok 返回值——Go 的风格是不抛异常,而是返回两个值。这是 Go 的标志性设计哲学。
Q7:for 是唯一的循环语句?
A: 对,Go 没有 while、也没有 do-while。只有 for,但用法灵活:
1 | // 经典 for 循环 |
少记几个关键字,也挺好。
Q8:函数可以返回多个值?
A: 可以,这是 Go 的杀手级特性之一:
1 | func divide(a, b float64) (float64, error) { |
还可以给返回值命名(命名返回值):
1 | func rect(l, w float64) (area, perimeter float64) { |
命名返回值适合返回值多的时候用,代码更清晰。
Q9:defer 是什么?为什么说它很优雅?
A: defer 延迟执行一个函数调用,直到当前函数返回前才执行:
1 | func readFile(path string) error { |
实际效果:
- 不管函数怎么退出(正常 return、panic),
defer都会执行 - 多个
defer按 LIFO(后进先出) 顺序执行 - 常用于:关闭文件、释放锁、恢复状态
这比 Java 的 try-finally 写起来舒服多了。
Q10:goroutine 和 channel 是什么?
A: Go 并发的两大基石。
goroutine — 极轻量级线程
1 | go func() { |
启动一个 goroutine 只需要 2KB 栈内存(对比操作系统线程的几 MB)。轻松创建百万级并发。
channel — goroutine 之间通信
1 | ch := make(chan string) |
核心理念:
Do not communicate by sharing memory; instead, share memory by communicating.
不要通过共享内存来通信,而要通过通信来共享内存。
这意味着:不用加锁了!数据通过 channel 传递,天然安全。
下期预告
下一篇我们会深入聊:结构体与方法(struct & method)、接口(interface)的鸭子类型设计、以及 error 处理的最佳实践。
TODO: 如果你对某个话题特别感兴趣,或者想跳过某些基础内容直接进阶,随时告诉我——这个学习节奏由你来定。