首页 > 基础资料 博客日记

Go 语言入门学习笔记基础版

2026-05-26 15:00:06基础资料围观12

极客资料网推荐Go 语言入门学习笔记基础版这篇文章给大家,欢迎收藏极客资料网享受知识的乐趣

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. 高频易错点汇总

  1. fmt.Scan 传参必须加 &,漏写直接编译报错
  2. 空切片不能直接下标赋值,必须使用 append 追加元素
  3. 数组 [...] 语法,仅能在定义并初始化时使用
  4. for range 遍历返回索引和值,无用索引必须用 _ 占位
  5. Map 必须先用 make 初始化,未初始化无法赋值
  6. Map 取值搭配 ok 判断 key 是否存在,区分零值与键不存在
  7. 结构体方法:修改数据用指针接收者,只读逻辑用值接收者
  8. Go 的 switch 默认自带 break,不会顺序穿透
  9. 变量定义后必须使用,否则编译报错

文章来源:https://www.cnblogs.com/zxr1002/p/20170294
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!

标签:

相关文章

本站推荐

标签云