





















本文档整合阶段性全部学习内容,包含基础语法、输入输出、流程控制、数组/切片、函数、Map、结构体、方法、指针等核心知识点,搭配代码示例、场景说明、易错提醒与实战练习,适合系统复习与查阅。
所有 Go 可执行文件固定格式:
package main
import "fmt"
func main() {
// 业务代码写在这里
}
package main:声明为主包,代表当前文件是可执行程序,而非库文件import "fmt":导入标准输入输出包,用于打印、读取控制台内容func main():程序入口函数,程序运行时自动执行,无参数、无返回值| 函数 | 是否自动换行 | 参数间自动加空格 | 支持格式化占位符 | 适用场景 |
|---|---|---|---|---|
fmt.Print() |
否 | 否 | 否 | 连续拼接简单内容 |
fmt.Println() |
是 | 是 | 否 | 日常常规打印(使用最多) |
fmt.Printf() |
否 | 否 | 是 | 格式化输出、变量拼接 |
%d:十进制整数%s:字符串%f:浮点数;%.2f 表示保留 2 位小数%v:通用占位符,可打印任意数据类型package main
import "fmt"
func main() {
name := "张三"
age := 20
fmt.Printf("姓名:%s,年龄:%d\n", name, age)
}
print() / println()
println("临时调试信息")
作用:接收用户在控制台输入的数据。
基础语法
var 变量名 数据类型
fmt.Scan(&变量名)
核心规则
&(取地址符),否则编译报错示例
package main
import "fmt"
func main() {
var num int
fmt.Print("请输入一个数字:")
fmt.Scan(&num)
fmt.Println("你输入的数字:", num)
// 一次性读取多个值
var a, b int
fmt.Scan(&a, &b)
fmt.Println(a, b)
}
完整写法
var 变量名 数据类型
var name string
var num int
定义并赋值
var age int = 18
类型推导(简写,推荐)
无需手动声明类型,编译器自动推断。
sex := "男"
基础单分支
if 条件表达式 {
// 条件成立执行代码
}
双分支 if-else
if 条件表达式 {
// 条件成立
} else {
// 条件不成立
}
多分支 else if
if score >= 90 {
fmt.Println("优秀")
} else if score >= 60 {
fmt.Println("及格")
} else {
fmt.Println("不及格")
}
实战示例:判断奇偶数
package main
import "fmt"
func main() {
var num int
fmt.Scan(&num)
if num%2 == 0 {
fmt.Println("偶数")
} else {
fmt.Println("奇数")
}
}
Go 语言 switch 默认自带 break,匹配成功后自动终止,无需手动添加。
写法 1:带表达式(等值匹配)
switch 变量/表达式 {
case 值1:
逻辑代码
case 值2:
逻辑代码
default:
// 所有case都不匹配时执行
}
示例:简易菜单选择
package main
import "fmt"
func main() {
var op int
fmt.Println("1.加法 2.减法")
fmt.Scan(&op)
switch op {
case 1:
fmt.Println("执行加法运算")
case 2:
fmt.Println("执行减法运算")
default:
fmt.Println("输入选项错误")
}
}
写法 2:无表达式(替代多 if 判断)
score := 85
switch {
case score >= 90:
fmt.Println("优秀")
case score >= 60:
fmt.Println("及格")
default:
fmt.Println("不及格")
}
补充规则
case 1,2,3:Go 语言没有 while、do-while,所有循环统一使用 for 实现。
写法 1:标准三段式(计数循环,最常用)
for 初始化语句; 循环条件; 后置语句 {
循环体
}
示例:打印 1 ~ 10
for i := 1; i <= 10; i++ {
fmt.Println(i)
}
写法 2:仅保留条件(等效 while 循环)
i := 1
for i <= 10 {
fmt.Println(i)
i++
}
写法 3:死循环
for {
// 无限循环,必须配合 break 退出
}
写法 4:for range 遍历(数组 / 切片 / Map 专用)
for 索引, 值 := range 容器 {
}
_遍历场景中,不需要使用索引时,用 _ 占位,避免「定义变量未使用」编译报错。
nums := []int{1, 2, 3, 4}
for _, v := range nums {
fmt.Println(v)
}
break
跳出当前所在循环,直接终止循环执行。
for i := 1; i <= 10; i++ {
if i == 5 {
break
}
fmt.Println(i)
}
continue
跳过本次循环剩余代码,直接进入下一次循环。
for i := 1; i <= 10; i++ {
if i == 5 {
continue
}
fmt.Println(i)
}
示例 1:打印直角三角形
for i := 1; i <= 5; i++ {
for j := 1; j <= i; j++ {
fmt.Print("* ")
}
fmt.Println()
}
示例 2:九九乘法表
for i := 1; i <= 9; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d*%d=%d\t", j, i, i*j)
}
fmt.Println()
}
定义语法
var 数组名 [长度]数据类型
var arr [3]int
多种初始化方式
// 1. 先定义,后赋值
var a [3]int
a[0] = 10
a[1] = 20
// 2. 定义同时赋值
var b [3]int = [3]int{1, 2, 3}
// 3. 自动推导长度 ...(仅定义+初始化时可用)
c := [...]int{4, 5, 6}
数组核心特点
易错点:var arr [...]int 单独声明数组写法非法,编译器无法推断长度。
切片基于数组实现,长度可变,实际开发优先使用切片。
定义与初始化
// 1. 声明空切片
var s1 []int
// 2. 直接初始化元素
s2 := []int{1, 3, 5, 7}
// 3. make 创建切片(参数:长度, 容量)
s3 := make([]int, 2, 5)
核心操作:append 追加元素
空切片不能直接通过下标赋值,必须使用 append 动态追加元素:
var s []int
s = append(s, 10)
s = append(s, 20, 30)
fmt.Println(s)
切片截取
语法:切片[起始下标:结束下标],含左不含右
s := []int{10, 20, 30, 40}
part := s[1:3]
fmt.Println(part) // 输出 [20 30]
切片易错写法
var s []int
s[0] = 10 // 运行报错:下标越界,空切片长度为0
语法格式
func 函数名(参数列表) 返回值类型 {
函数体
return 返回值
}
示例:两数求和
func add(a int, b int) int {
return a + b
}
一个函数可以同时返回多个结果。
// 返回两数之和、两数之差
func calc(a, b int) (int, int) {
return a + b, a - b
}
func main() {
sum, sub := calc(10, 4)
fmt.Println(sum, sub)
// 匿名变量 _ 忽略不需要的返回值
_, sub2 := calc(20, 7)
fmt.Println(sub2)
}
格式:参数名 ...数据类型,支持传入任意个数同类型参数,函数内部按切片处理。
// 对任意个整数求和
func sum(nums ...int) int {
total := 0
for _, v := range nums {
total += v
}
return total
}
func main() {
fmt.Println(sum(1, 2))
fmt.Println(sum(1, 2, 3, 4))
}
无函数名,可定义后立即执行,也可赋值给变量调用。
func main() {
// 写法1:定义并立即执行
func(a, b int) {
fmt.Println(a * b)
}(3, 5)
// 写法2:赋值给变量,重复调用
f := func(x int) {
fmt.Println(x * x)
}
f(6)
}
存储 key-value 格式数据,键唯一,遍历顺序无序。
Map 必须使用 make 初始化,未初始化直接赋值会报错。
// 格式:map[键类型]值类型
user := make(map[string]string)
// 新增 / 修改元素(key存在则覆盖,不存在则新增)
user["name"] = "张三"
user["age"] = "20"
Map 获取不存在的键,不会报错,会返回对应类型零值。通过第二个返回值 ok 判断键是否真实存在。
age, ok := user["name"]
if ok {
fmt.Println("键存在,值:", age)
} else {
fmt.Println("该键不存在")
}
age:key 对应的值ok:布尔类型,true = 键存在,false = 键不存在使用内置函数 delete(map对象, key)
delete(user, "name")
for k, v := range user {
fmt.Println(k, ":", v)
}
结构体用于封装一组不同类型的数据,自定义现实事物模型。
type 结构体名 struct {
字段名 字段类型
}
type Student struct {
Name string
Age int
}
func main() {
// 方式1:键值对赋值(推荐,可读性强)
s1 := Student{
Name: "小明",
Age: 18,
}
// 方式2:按字段顺序赋值
s2 := Student{"小红", 19}
// 访问结构体字段
fmt.Println(s1.Name, s1.Age)
}
方法是绑定在结构体上的函数,分为「值接收者」和「指针接收者」。
func (接收者变量 结构体类型) 方法名() {}
type Person struct {
Name string
Age int
}
// 只读方法:值接收者
func (p Person) GetName() string {
return p.Name
}
// 反面示例:尝试用值接收者修改数据(无效)
func (p Person) Rename(newName string) {
p.Name = newName // 仅修改副本,原数据不变
}
func (接收者变量 *结构体类型) 方法名() {}
// 可修改数据:指针接收者
func (p *Person) SetName(newName string) {
p.Name = newName
}
&:取地址符,获取变量的内存地址*:解引用符,根据地址读写对应的值func main() {
a := 10
fmt.Println("变量a的地址:", &a)
// 定义指针变量,存储 int 类型地址
var p *int
p = &a
// 通过指针修改原变量值
*p = 20
fmt.Println("修改后 a 的值:", a)
}
Go 函数参数默认值传递,普通传参只能修改副本;使用指针传参可直接修改外部原变量。
普通传参(无法修改原值)
func change(num int) {
num = 100
}
指针传参(可修改原值)
func change(num *int) {
*num = 100
}
func main() {
x := 10
change(&x)
fmt.Println(x) // 输出 100
}
fmt.Scan 传参必须加 &,漏写直接编译报错append 追加元素[...] 语法,仅能在定义并初始化时使用for range 遍历返回索引和值,无用索引必须用 _ 占位make 初始化,未初始化无法赋值ok 判断 key 是否存在,区分零值与键不存在此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。