现在让我们设好番茄钟放一首好听的音乐开始学习吧 🌈 😋
Go 语言特点与优势
Go(又称 Golang)是 Google 于 2009 年推出的开源编程语言,由 Robert Griesemer、Rob Pike 和 Ken Thompson 设计。
核心特点
1. 简洁高效
- 语法简洁,关键字仅 25 个
- 编译速度极快,接近解释型语言的开发效率
- 代码可读性强,易于维护
2. 原生并发支持
- 内置 goroutine(轻量级线程)
- channel 实现优雅的并发通信
- 单机可轻松支持数万并发
3. 垃圾回收
- 自动内存管理,无需手动释放
- GC 性能持续优化,停顿时间极短
4. 静态类型 + 类型推断
- 编译期类型检查,减少运行时错误
- 支持类型推断,减少冗余代码
5. 丰富的标准库
- 网络、HTTP、JSON、加密等开箱即用
- 跨平台支持(Windows/Linux/macOS)
6. 部署简单
- 编译生成单一可执行文件
- 无需依赖外部运行时环境
- 跨平台编译支持
应用场景
- 云原生基础设施:Docker、Kubernetes、Etcd
- 微服务架构:高性能 API 网关、RPC 服务
- Web 后端:高并发 Web 应用
- DevOps 工具:命令行工具、自动化脚本
- 数据处理:日志分析、数据采集
与其他语言对比
| 特性 | Go | Java | Python | C++ |
|---|---|---|---|---|
| 性能 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐⭐⭐ |
| 并发支持 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |
| 学习曲线 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| 开发效率 | ⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐⭐⭐ | ⭐⭐ |
| 部署难度 | ⭐⭐⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐⭐ | ⭐⭐ |
前言
Go语言以简洁、高效著称。本文从零开始,系统梳理 Go 核心语法,涵盖变量、类型、流程控制、函数等核心知识点,助你快速上手 Go 编程。
1. Hello World 与基础结构
第一个程序
- 首先需要在go的官网上去下载安装包

下载完成之后选择自己想要安装的路径傻瓜式安装即可,下载完之后需添加环境变量,重启电脑之后在命令行终端运行
go version

这样go运行的基础环境就已经搭建好了 🌈
- 市面上已经有很多较为成熟的go ide 这里我还是使用我们的老朋友vscode,配合golang的插件来编写我们的第一个go程序吧 🤗
打开vscode之后安装这两个插件即可

然后就可以打开一个文件夹,新建一个main.go的文件:

刚才的两个插件拥有极其强大的语法提示,在开始构建运行体时,只需要 ‘pk’就可以自动生成默认的执行体


现在我们就可以编写第一个go语言程序了
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
运行
go run ./main.go

关键点:
package main:可执行程序的入口包import:导入标准库或第三方包func main():程序执行起点- 语句结尾无需分号
2. 变量声明
2.1 标准声明
var name string = "张三"
var age int = 20
var isOk bool
2.2 批量声明
var (
username string = "李四"
age int = 25
isActive bool = true
)
2.3 类型推导
var name = "王五" // 自动推断为 string
var age = 30 // 自动推断为 int
2.4 短变量声明(常用)
name := "赵六"
age := 28
注意:
:=只能在函数内部使用,不能用于全局变量。
2.5 匿名变量
func getInfo() (int, string) {
return 10, "张三"
}
_, username := getInfo() // 使用 _ 忽略不需要的返回值
3. 常量声明
3.1 基本声明
const pi = 3.1415
const e = 2.7182
3.2 批量声明
const (
StatusOK = 200
StatusError = 500
)
3.3 iota 计数器
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
)
// iota在这里会进行累加和其他的语言的枚举相似
4. 基本数据类型
4.1 整型
| 类型 | 范围 | 说明 |
|---|---|---|
| int8 | -128 ~ 127 | 1字节 |
| int16 | -32768 ~ 32767 | 2字节 |
| int32 | -2^31 ~ 2^31-1 | 4字节 |
| int64 | -2^63 ~ 2^63-1 | 8字节 |
| uint8 | 0 ~ 255 | 无符号1字节 |
| int | 平台相关 | 32位系统4字节,64位系统8字节 |
var age int = 25
var count int64 = 1000000
4.2 浮点型
var price float32 = 99.99
var pi float64 = 3.1415926535
默认类型: Go中浮点数默认为
float64
4.3 布尔型
var isActive bool = true
var isDeleted bool = false
注意: 布尔值不能与数值类型互相转换。
4.4 字符串
// 普通字符串
str1 := "Hello, Go!"
// 多行字符串(原始字符串)
str2 := `第一行
第二行
第三行`
// 字符串拼接
name := "张" + "三"
result := fmt.Sprintf("%s,年龄:%d", "李四", 25)
常用操作:
import "strings"
len("hello") // 5 - 长度
strings.Contains("hello", "ll") // true - 包含判断
strings.Split("a-b-c", "-") // ["a", "b", "c"] - 分割
strings.Join([]string{"a", "b"}, "-") // "a-b" - 拼接
4.5 byte 和 rune
var b byte = 'a' // byte = uint8,表示ASCII字符
var r rune = '中' // rune = int32,表示Unicode字符
遍历字符串:
str := "hello中国"
// 按字节遍历
for i := 0; i < len(str); i++ {
fmt.Printf("%c ", str[i])
}
// 按字符遍历(推荐处理中文)
for _, char := range str {
fmt.Printf("%c ", char)
}
5. 类型转换
5.1 数值类型转换
var a int8 = 20
var b int16 = 40
var c = int16(a) + b // 必须显式转换
重要: Go没有隐式类型转换,必须显式转换。
5.2 转换为字符串
import "strconv"
// int → string
str1 := strconv.Itoa(123)
// float → string
str2 := strconv.FormatFloat(3.14, 'f', 2, 64)
// bool → string
str3 := strconv.FormatBool(true)
// 使用 fmt.Sprintf
str4 := fmt.Sprintf("%d", 456)
5.3 字符串转数值
// string → int
num, _ := strconv.Atoi("123")
// string → int64
num64, _ := strconv.ParseInt("123", 10, 64)
// 10表示十进制, 64表示int64 即 8byte长整型, 也可以选用32
// string → float
floatNum, _ := strconv.ParseFloat("3.14", 64)
// string → bool
boolVal, _ := strconv.ParseBool("true")
6. 运算符
6.1 算术运算符
+ - * / %
// 注意:Go没有 ++ -- 作为表达式
count := 10
count++ // 正确:独立语句
// x := count++ // 错误!
6.2 关系运算符
== != > >= < <=
if age >= 18 {
fmt.Println("成年")
}
6.3 逻辑运算符
&& || !
if age > 18 && age < 60 {
fmt.Println("工作年龄")
}
6.4 赋值运算符
= += -= *= /= %=
x := 10
x += 5 // x = x + 5
7. 流程控制
7.1 if-else
score := 85
if score >= 90 {
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
特殊写法(变量作用域限定):
if score := 56; score >= 90 {
fmt.Println("优秀")
} else {
fmt.Println("一般")
}
// score 在此处不可用, 这样可以减少作用域中的命名冗余
7.2 for 循环
基本形式:
for i := 0; i < 10; i++ {
fmt.Println(i)
}
类似 while:
i := 0
for i < 10 {
fmt.Println(i)
i++
}
无限循环:
for {
if condition {
break
}
}
7.3 for range(遍历)
str := "hello"
for index, char := range str {
fmt.Printf("%d: %cn", index, char)
}
// 只要值
for _, char := range str {
fmt.Printf("%c ", char)
}
7.4 switch
day := 3
switch day {
case 1:
fmt.Println("周一")
case 2:
fmt.Println("周二")
case 3, 4, 5:
fmt.Println("工作日")
default:
fmt.Println("周末")
}
特点: Go的switch自动break,无需手动添加。
无表达式的switch:
age := 25
switch {
case age < 18:
fmt.Println("未成年")
case age >= 18 && age < 60:
fmt.Println("成年")
default:
fmt.Println("老年")
}
7.5 break 和 continue
// break:跳出循环
for i := 0; i < 10; i++ {
if i == 5 {
break
}
}
// continue:跳过本次循环
for i := 0; i < 10; i++ {
if i%2 == 0 {
continue
}
fmt.Println(i) // 只打印奇数
}
带标签的跳转:
outer:
for i := 0; i < 3; i++ {
for j := 0; j < 3; j++ {
if j == 2 {
break outer // 跳出外层循环
}
}
}
7.6 goto(慎用)
func main() {
i := 0
loop:
if i < 5 {
fmt.Println(i)
i++
goto loop
}
}
8. 函数(Function)
函数是 Go 程序的基本组成单元。Go 支持多返回值、命名返回值、可变参数等特性。
8.1 函数声明
基本语法:
func 函数名(参数列表) 返回值类型 {
函数体
}
示例:
// 无参数无返回值
func sayHello() {
fmt.Println("Hello")
}
// 有参数有返回值
func add(a int, b int) int {
return a + b
}
// 相同类型参数简写
func add(a, b int) int {
return a + b
}
// 多个返回值
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为0")
}
return a / b, nil
}
8.2 多返回值
Go 函数可以返回多个值,常用于返回结果和错误信息。
func getUserInfo(id int) (string, int, error) {
if id <= 0 {
return "", 0, fmt.Errorf("无效的用户ID")
}
return "张三", 25, nil
}
// 使用
name, age, err := getUserInfo(1)
if err != nil {
fmt.Println("错误:", err)
return
}
fmt.Printf("用户: %s, 年龄: %dn", name, age)
// 忽略部分返回值
name, _, _ := getUserInfo(1)
8.3 命名返回值
返回值可以预先命名,函数体内直接赋值,return 可省略返回值列表。
func calculate(a, b int) (sum int, diff int) {
sum = a + b
diff = a - b
return // 等价于 return sum, diff
}
// 使用
sum, diff := calculate(10, 5)
fmt.Println(sum, diff) // 15 5
注意: 命名返回值会自动初始化为零值。
func test() (count int, name string, ok bool) {
// 未赋值时:count=0, name="", ok=false
return
}
8.4 可变参数
使用 ... 接收任意数量的同类型参数,可变参数在函数内部是切片。
// 求和函数
func sum(nums ...int) int {
total := 0
for _, num := range nums {
total += num
}
return total
}
// 使用
fmt.Println(sum(1, 2, 3)) // 6
fmt.Println(sum(1, 2, 3, 4, 5)) // 15
// 切片展开
numbers := []int{10, 20, 30}
fmt.Println(sum(numbers...)) // 60
混合参数:
func printInfo(prefix string, values ...int) {
fmt.Print(prefix, ": ")
for _, v := range values {
fmt.Print(v, " ")
}
fmt.Println()
}
printInfo("数字", 1, 2, 3, 4, 5) // 数字: 1 2 3 4 5
注意: 可变参数必须是函数参数列表的最后一个。
8.5 匿名函数与闭包
匿名函数:
// 直接调用
func() {
fmt.Println("匿名函数")
}()
// 赋值给变量
add := func(a, b int) int {
return a + b
}
fmt.Println(add(3, 5)) // 8
闭包(Closure):
闭包是引用了外部变量的匿名函数。
// 计数器闭包
func counter() func() int {
count := 0
return func() int {
count++
return count
}
}
c1 := counter()
fmt.Println(c1()) // 1
fmt.Println(c1()) // 2
fmt.Println(c1()) // 3
c2 := counter() // 新的闭包实例
fmt.Println(c2()) // 1

闭包的典型应用 – 函数工厂:
// 生成加法器
func adder(base int) func(int) int {
return func(x int) int {
return base + x
}
}
add10 := adder(10)
add100 := adder(100)
fmt.Println(add10(5)) // 15
fmt.Println(add100(5)) // 105
8.6 defer 延迟调用
defer 用于延迟函数调用,在函数返回前执行(常用于资源清理)。
基本用法:
func main() {
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
fmt.Println("开始")
}
// 输出:
// 开始
// 3
// 2
// 1
执行顺序: defer 遵循 后进先出(LIFO) 原则。
典型应用 – 文件操作:
func readFile(filename string) error {
file, err := os.Open(filename)
if err != nil {
return err
}
defer file.Close() // 确保文件关闭
// 读取文件内容
// ...
return nil
}
典型应用 – 锁释放:
var mu sync.Mutex
func criticalSection() {
mu.Lock()
defer mu.Unlock() // 确保锁被释放
// 临界区代码
// ...
}
defer 与返回值:
func test() (result int) {
defer func() {
result++ // defer 可以修改命名返回值
}()
return 10
}
fmt.Println(test()) // 11
8.7 函数作为参数(高阶函数)
函数可以作为参数传递给其他函数。
// 定义函数类型
type operation func(int, int) int
// 接受函数作为参数
func calculate(a, b int, op operation) int {
return op(a, b)
}
// 使用
add := func(x, y int) int { return x + y }
multiply := func(x, y int) int { return x * y }
fmt.Println(calculate(5, 3, add)) // 8
fmt.Println(calculate(5, 3, multiply)) // 15
实用示例 – 过滤函数:
func filter(nums []int, test func(int) bool) []int {
result := []int{}
for _, num := range nums {
if test(num) {
result = append(result, num)
}
}
return result
}
// 筛选偶数
isEven := func(n int) bool { return n%2 == 0 }
nums := []int{1, 2, 3, 4, 5, 6}
fmt.Println(filter(nums, isEven)) // [2 4 6]
8.8 函数类型与方法
定义函数类型:
type Calculator func(int, int) int
func (c Calculator) Description() string {
return "这是一个计算器函数"
}
var add Calculator = func(a, b int) int {
return a + b
}
fmt.Println(add(1, 2)) // 3
fmt.Println(add.Description()) // 这是一个计算器函数
8.9 递归函数
函数可以调用自身实现递归。
示例1:阶乘
func factorial(n int) int {
if n <= 1 {
return 1
}
return n * factorial(n-1)
}
fmt.Println(factorial(5)) // 120
示例2:斐波那契数列
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
fmt.Println(fibonacci(7)) // 13
注意: 递归需要明确终止条件,避免无限递归导致栈溢出。
8.10 init 函数
init() 是特殊函数,在 main() 之前自动执行,用于初始化操作。
package main
import "fmt"
var globalVar int
func init() {
fmt.Println("init 函数执行")
globalVar = 100
}
func main() {
fmt.Println("main 函数执行")
fmt.Println(globalVar) // 100
}
// 输出:
// init 函数执行
// main 函数执行
// 100
特点:
- 不能被显式调用
- 一个包可以有多个
init()函数 - 执行顺序:常量 → 变量 →
init()→main()
8.11 函数练习
练习1:实现一个泛型 Max 函数(使用接口)
func max(a, b int) int {
if a > b {
return a
}
return b
}
练习2:实现 Map 高阶函数
func mapInt(nums []int, fn func(int) int) []int {
result := make([]int, len(nums))
for i, num := range nums {
result[i] = fn(num)
}
return result
}
// 使用
double := func(n int) int { return n * 2 }
nums := []int{1, 2, 3, 4, 5}
fmt.Println(mapInt(nums, double)) // [2 4 6 8 10]
练习3:实现带超时的重试函数
func retry(attempts int, fn func() error) error {
for i := 0; i < attempts; i++ {
err := fn()
if err == nil {
return nil
}
fmt.Printf("尝试 %d 失败: %vn", i+1, err)
}
return fmt.Errorf("超过最大重试次数")
}
9. fmt 包常用函数
8.1 Print 系列
fmt.Print("hello") // 不换行
fmt.Println("world") // 换行
fmt.Printf("age=%d", 25) // 格式化输出
8.2 常用占位符
| 占位符 | 说明 | 示例 |
|---|---|---|
| %v | 默认格式 | fmt.Printf("%v", 123) |
| %T | 类型 | fmt.Printf("%T", 123) |
| %d | 十进制整数 | fmt.Printf("%d", 123) |
| %f | 浮点数 | fmt.Printf("%.2f", 3.14) |
| %s | 字符串 | fmt.Printf("%s", "hello") |
| %t | 布尔值 | fmt.Printf("%t", true) |
| %c | 字符 | fmt.Printf("%c", 'A') |
10. 命名规则与代码风格
9.1 命名规则
- 组成: 字母、数字、下划线,首字符不能是数字
- 大小写敏感:
age和Age是不同变量 - 关键字禁用: 不能使用
for、if、func等保留字 - 驼峰式命名:
userName、getUserInfo - 见名知意: 变量用名词,函数用动词
可见性规则:
- 大写字母开头: 公开(可导出)
- 小写字母开头: 私有(包内可见)
var PublicVar = "可导出" // 其他包可访问
var privateVar = "私有" // 仅包内可访问
9.2 代码风格
- 无需分号: 行尾不写
; - 左括号不换行:
// 正确
if x > 0 {
fmt.Println("positive")
}
// 错误
if x > 0
{
fmt.Println("positive")
}
- 使用
<strong>go fmt</strong>格式化代码:
go fmt main.go
11. 注释
// 单行注释
/*
多行注释
可以跨越多行
*/
快捷键: Win:
Ctrl+/| Mac:Cmd+/
12. 实战练习
综合练习1:用户管理系统
package main
import "fmt"
type User struct {
ID int
Name string
Age int
}
// 创建用户
func createUser(id int, name string, age int) User {
return User{ID: id, Name: name, Age: age}
}
// 验证用户年龄
func validateAge(age int) error {
if age < 0 || age > 150 {
return fmt.Errorf("年龄无效: %d", age)
}
return nil
}
// 打印用户信息
func printUser(u User) {
fmt.Printf("ID: %d, 姓名: %s, 年龄: %dn", u.ID, u.Name, u.Age)
}
func main() {
user := createUser(1, "张三", 25)
if err := validateAge(user.Age); err != nil {
fmt.Println("错误:", err)
return
}
printUser(user)
}
综合练习2:简易计算器
func calculator() {
var num1, num2 float64
var operator string
fmt.Print("请输入第一个数字: ")
fmt.Scan(&num1)
fmt.Print("请输入运算符 (+, -, *, /): ")
fmt.Scan(&operator)
fmt.Print("请输入第二个数字: ")
fmt.Scan(&num2)
switch operator {
case "+":
fmt.Printf("%.2f + %.2f = %.2fn", num1, num2, num1+num2)
case "-":
fmt.Printf("%.2f - %.2f = %.2fn", num1, num2, num1-num2)
case "*":
fmt.Printf("%.2f * %.2f = %.2fn", num1, num2, num1*num2)
case "/":
if num2 == 0 {
fmt.Println("错误:除数不能为0")
return
}
fmt.Printf("%.2f / %.2f = %.2fn", num1, num2, num1/num2)
default:
fmt.Println("无效的运算符")
}
}
原有练习
练习4:求两数最大值
func max(a, b int) int {
if a > b {
return a
}
return b
}
练习5:九九乘法表
for i := 1; i <= 9; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d×%d=%dt", i, j, i*j)
}
fmt.Println()
}
练习6:判断成绩等级
func getGrade(score int) string {
switch {
case score >= 90:
return "优秀"
case score >= 60:
return "及格"
default:
return "不及格"
}
}
13. 易错点总结
- 变量声明后必须使用,否则编译报错
<strong>:=</strong>只能在函数内使用- 没有隐式类型转换,必须显式转换
<strong>++</strong>和<strong>--</strong>只能作为独立语句- Go 没有三元运算符
- switch 默认自动 break
- 左括号必须与语句在同一行
总结
Go语法简洁高效,核心要点:
- 变量声明: 优先使用
:= - 类型转换: 必须显式转换
- 流程控制:
for是唯一循环,switch自动 break - 代码风格: 使用
go fmt保持一致 - 命名规范: 驼峰式,大写公开、小写私有
学习路径建议:
- 基础巩固:变量、类型、流程控制、函数(本文内容)
- 进阶特性:数组、切片、Map、结构体
- 面向对象:方法、接口、组合
- 并发编程:goroutine、channel、sync 包
- 标准库:io、net/http、database/sql
- 项目实战:Web 服务、RESTful API、微服务
推荐资源:
- 官方文档:https://go.dev/doc/
- Go by Example:https://gobyexample.com/
- The Go Programming Language(书籍)
