首页 > 基础资料 博客日记
Go 语言入门学习笔记基础版
2026-05-26 15:00:06基础资料围观12次
Go 语言入门学习笔记基础版
文档说明
本文档整合阶段性全部学习内容,包含基础语法、输入输出、流程控制、数组/切片、函数、Map、结构体、方法、指针等核心知识点,搭配代码示例、场景说明、易错提醒与实战练习,适合系统复习与查阅。
1. 程序基础结构
1.1 标准可执行程序模板
所有 Go 可执行文件固定格式:
package main
import "fmt"
func main() {
// 业务代码写在这里
}
package main:声明为主包,代表当前文件是可执行程序,而非库文件import "fmt":导入标准输入输出包,用于打印、读取控制台内容func main():程序入口函数,程序运行时自动执行,无参数、无返回值
2. 输入与输出
2.1 三类标准打印函数(fmt 包)
| 函数 | 是否自动换行 | 参数间自动加空格 | 支持格式化占位符 | 适用场景 |
|---|---|---|---|---|
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)
}
2.2 内置原生打印函数
print() / println()
- 无需导入 fmt 包,Go 语言内置
- 功能简单,仅用于临时调试
- 正式项目、生产环境禁止使用
println("临时调试信息")
2.3 控制台输入 fmt.Scan
作用:接收用户在控制台输入的数据。
基础语法
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)
}
3. 变量基础
3.1 变量定义与初始化
完整写法
var 变量名 数据类型
var name string
var num int
定义并赋值
var age int = 18
类型推导(简写,推荐)
无需手动声明类型,编译器自动推断。
sex := "男"
3.2 变量使用规则
- 定义后的变量必须使用,否则编译报错
- 变量名区分大小写
- 同一代码块内,变量名不能重复定义
4. 条件判断
4.1 if / else 分支判断
基础单分支
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("奇数")
}
}
4.2 switch 分支语句
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 可匹配多个值:
case 1,2,3: - default 可选,建议写在所有 case 最后
5. 循环结构(Go 仅支持 for)
Go 语言没有 while、do-while,所有循环统一使用 for 实现。
5.1 四种常用 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 容器 {
}
5.2 匿名变量 _
遍历场景中,不需要使用索引时,用 _ 占位,避免「定义变量未使用」编译报错。
nums := []int{1, 2, 3, 4}
for _, v := range nums {
fmt.Println(v)
}
5.3 循环控制关键字
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)
}
5.4 双层嵌套循环
- 外层循环:控制行数
- 内层循环:控制每行内容
示例 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()
}
6. 数组与切片
6.1 数组(长度固定)
定义语法
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}
数组核心特点
- 长度在编译阶段确定,定义后无法修改
- 元素下标从 0 开始
- 属于值类型,赋值、函数传参时会完整拷贝数据
易错点:var arr [...]int 单独声明数组写法非法,编译器无法推断长度。
6.2 切片 Slice(动态数组,开发首选)
切片基于数组实现,长度可变,实际开发优先使用切片。
定义与初始化
// 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
7. 函数
7.1 基础函数
语法格式
func 函数名(参数列表) 返回值类型 {
函数体
return 返回值
}
示例:两数求和
func add(a int, b int) int {
return a + b
}
7.2 多返回值(Go 语言特色)
一个函数可以同时返回多个结果。
// 返回两数之和、两数之差
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)
}
7.3 可变参数
格式:参数名 ...数据类型,支持传入任意个数同类型参数,函数内部按切片处理。
// 对任意个整数求和
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))
}
7.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)
}
8. Map 键值对(字典)
存储 key-value 格式数据,键唯一,遍历顺序无序。
8.1 定义与初始化
Map 必须使用 make 初始化,未初始化直接赋值会报错。
// 格式:map[键类型]值类型
user := make(map[string]string)
// 新增 / 修改元素(key存在则覆盖,不存在则新增)
user["name"] = "张三"
user["age"] = "20"
8.2 取值 + 判断 Key 是否存在
Map 获取不存在的键,不会报错,会返回对应类型零值。通过第二个返回值 ok 判断键是否真实存在。
age, ok := user["name"]
if ok {
fmt.Println("键存在,值:", age)
} else {
fmt.Println("该键不存在")
}
age:key 对应的值ok:布尔类型,true= 键存在,false= 键不存在
8.3 删除元素
使用内置函数 delete(map对象, key)
delete(user, "name")
8.4 Map 遍历
for k, v := range user {
fmt.Println(k, ":", v)
}
9. 结构体 struct
结构体用于封装一组不同类型的数据,自定义现实事物模型。
9.1 结构体定义
type 结构体名 struct {
字段名 字段类型
}
type Student struct {
Name string
Age int
}
9.2 结构体实例化与赋值
func main() {
// 方式1:键值对赋值(推荐,可读性强)
s1 := Student{
Name: "小明",
Age: 18,
}
// 方式2:按字段顺序赋值
s2 := Student{"小红", 19}
// 访问结构体字段
fmt.Println(s1.Name, s1.Age)
}
10. 结构体方法
方法是绑定在结构体上的函数,分为「值接收者」和「指针接收者」。
10.1 值接收者
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 // 仅修改副本,原数据不变
}
10.2 指针接收者
func (接收者变量 *结构体类型) 方法名() {}
- 直接操作原结构体内存地址
- 可以修改原结构体数据
- 适用场景:更新 / 修改字段;结构体较大时,减少拷贝开销
// 可修改数据:指针接收者
func (p *Person) SetName(newName string) {
p.Name = newName
}
10.3 选用口诀
- 只读取数据 → 使用 值接收者
- 需要修改数据 / 结构体体积大 → 使用 指针接收者
11. 指针基础
11.1 两个核心符号
&:取地址符,获取变量的内存地址*:解引用符,根据地址读写对应的值
11.2 基础使用
func main() {
a := 10
fmt.Println("变量a的地址:", &a)
// 定义指针变量,存储 int 类型地址
var p *int
p = &a
// 通过指针修改原变量值
*p = 20
fmt.Println("修改后 a 的值:", a)
}
11.3 指针作为函数参数
Go 函数参数默认值传递,普通传参只能修改副本;使用指针传参可直接修改外部原变量。
普通传参(无法修改原值)
func change(num int) {
num = 100
}
指针传参(可修改原值)
func change(num *int) {
*num = 100
}
func main() {
x := 10
change(&x)
fmt.Println(x) // 输出 100
}
12. 全套实战练习题
基础练习
- 循环顺序打印 1 ~ 10
- 计算 1 ~ 100 所有数字累加和
- 输入数字,判断奇数 / 偶数
- 筛选 1~100 中所有偶数、能被 3 整除的数字
进阶练习
- 双层循环:打印直角三角形、九九乘法表
- 猜数字小游戏(for + if + break)
- 切片遍历、切片求和、求切片最大值与最小值
- 简易菜单计算器(Scan + switch + 函数)
- 学生信息管理(结构体 + Map + 方法)
13. 高频易错点汇总
fmt.Scan传参必须加&,漏写直接编译报错- 空切片不能直接下标赋值,必须使用
append追加元素 - 数组
[...]语法,仅能在定义并初始化时使用 for range遍历返回索引和值,无用索引必须用_占位- Map 必须先用
make初始化,未初始化无法赋值 - Map 取值搭配
ok判断 key 是否存在,区分零值与键不存在 - 结构体方法:修改数据用指针接收者,只读逻辑用值接收者
- Go 的 switch 默认自带 break,不会顺序穿透
- 变量定义后必须使用,否则编译报错
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:

