golang 8函数
-
摘要
本视频专注于Go语言中的函数定义与使用。首先介绍了Go语言支持普通函数及匿名函数,强调了函数作为一等公民的特性,即函数本身可以当作变量传递。接着详细讲解了函数定义的基本要素,包括函数关键字、名称、参数(参数名称和类型)、返回值类型等。特别强调了Go语言中函数可以返回多个值的特点。最后通过实例演示了函数的调用过程,包括值传递的概念和细节,并通过图文解释了值传递的工作原理。整体内容旨在帮助学习者掌握Go语言中函数的基础知识和应用方法。
-
分段总结
折叠
00:01Go语言函数定义
1.Go语言支持普通函数和匿名函数。 2.函数是一等公民,可以当作变量传递。 3.函数定义包括函数关键字、函数名称、参数和返回类型。
02:30函数定义要素
1.函数关键字为func。 2.函数名称用于标识函数。 3.函数参数包括参数名称和参数类型。 4.返回类型指定函数返回值的类型,Go语言支持返回多个值。
04:55函数调用
1.函数调用通过函数名称和参数列表进行。 2.函数返回值通过变量接收。 3.示例:调用加法函数并打印结果。
06:47函数参数传递
1.Go语言中函数参数是值传递。 2.值传递意味着函数接收参数的副本。 3.修改函数内部的参数副本不会影响外部原始数据。
08:05值传递的原理
1.函数调用时,参数被拷贝到函数内部。 2.函数内部对参数的操作基于拷贝的副本进行。 3.函数返回结果,外部接收并使用。 4.值传递确保函数内部逻辑不会修改外部原始数据。
一、函数的定义 00:14
1. 函数的构成要素 02:30
-
关键字:Go语言使用func关键字定义函数,与其他语言不同
-
一等公民特性
:
-
函数可作为变量传递
-
支持匿名函数和闭包
-
函数可以满足接口
-
-
多值返回:Go函数可返回多个值,如(int, error)
1)函数名称 02:41
-
命名规则:函数名应明确表达功能,如add表示加法运算
-
位置要求:可定义在main函数之外,与main函数同级
2)参数 03:00
-
参数格式:先写参数名后写类型,如a int
-
多参数简写:相同类型参数可合并,如(a,b int)
-
混合类型:不同类型参数需分开声明,如(a int, b float32)
3)返回值 03:30
-
单返回值:直接写类型,如int
-
多返回值:用括号括起,如(int, error)
-
返回值位置:在参数列表后声明,语法较特殊
4)return语句 04:00
-
强制要求:函数必须有return语句返回声明类型的值
-
多值返回:用逗号分隔,如return a+b, nil
-
错误处理:常将error作为最后一个返回值
5)函数的简写 04:35
-
参数类型合并:相同类型参数可简写,如(a,b int)
-
匿名返回值:可不命名返回值变量,直接return表达式
2. 多值返回 05:16
1)示例
-
接收方式:用逗号分隔变量接收,如sum, err := add(1,2)
-
忽略返回值:用下划线_忽略不需要的返回值
2)示例 06:18
-
类型安全:不同类型参数不能合并声明
-
参数顺序:需保持参数传递顺序与声明一致
3. 值传递 06:50
1)值传递的定义 08:19
-
本质:Go中所有参数传递都是值传递(拷贝)
-
影响:函数内修改参数不影响原始变量
-
函数参数
-
拷贝机制:调用时参数值会被完整拷贝
-
内存模型:形参和实参位于不同内存地址
-
-
值传递示例
09:47
-
修改测试:函数内修改参数a=3不影响外部变量
-
打印验证:外部打印变量保持原始值
-
指针例外:通过指针可修改原始变量(后续讲解)
二、知识小结
知识点 核心内容 重点/易混淆点 难度系数 函数定义 使用func关键字定义,包含函数名、参数列表和返回值类型 参数类型简写:相同类型参数可合并声明多返回值:Go特有功能 ⭐⭐ 函数特性 函数是一等公民:1. 可作为变量传递2. 支持匿名函数和闭包3. 可满足接口 与静态语言对比:传统静态语言函数不能作为变量与动态语言对比:动态语言开发者可能不敏感此特性 ⭐⭐⭐⭐ 参数传递 Go语言全部采用值传递机制- 基本类型直接复制值- 复合类型复制指针(但仍是值传递) slice特殊表现:看似引用传递实为包含指针的结构体值传递修改外部变量:需使用指针参数 ⭐⭐⭐⭐ 返回值处理 支持多值返回:return a, b使用_忽略不需要的返回值 返回值位置:在参数列表后声明类型约束:必须返回声明类型的值 ⭐⭐ 函数调用 通过函数名直接调用多返回值需对应数量变量接收 匿名变量:使用_占位不需要的返回值返回值校验:常配合error类型使用 ⭐ 值传递原理 通过"篮子"比喻说明参数传递机制:1. 调用时复制参数值2. 内部修改不影响原始变量 指针突破限制:通过传递指针可修改外部变量性能影响:大对象值传递有拷贝开销 ⭐⭐⭐ 函数分类 1. 普通函数2. 匿名函数3. 闭包 接口实现:函数可作为接口的实现高阶函数:函数作为参数或返回值 ⭐⭐⭐ -
摘要
该视频主要讲述了函数返回值的概念和变长参数的处理。首先介绍了函数在某些情况下可以没有返回值,然后讲解了函数的返回值可以是单值、多值或无值,并可以通过类型和变量名来定义返回值。此外,还提到了省略号在定义多个值时的用法,可以一次性传递多个变量给函数。最后通过示例演示了如何使用函数返回多个值。此外,视频还讲述了在编程中如何处理变长参数的问题,包括变长参数的实质、限制和如何使用。
-
分段总结
折叠
00:01函数的返回值
1.函数的返回值可以是单值、多值或无值。 2.某些函数如初始化函数或无限循环函数可能不需要返回值。 3.无返回值函数可以没有参数和返回值。
01:27返回值的多重定义
1.函数在定义时除了指定返回类型外,还可以显式指定返回值变量的名称。 2.这种定义方式可以省略var关键字,直接使用变量名。 3.返回值变量名在函数内部是可见的,方便直接使用。
03:04返回值的默认值
1.如果函数定义了返回值变量,但没有在return语句中明确指定返回值,则会默认返回之前定义的变量值。 2.这种默认返回值的方式在许多源码中常见。
03:53可变参数函数
1.省略号(...)用于定义可变参数函数,可以接受任意数量的参数。 2.可变参数函数在静态语言中通过特定的语法定义,允许传入不同数量的参数。 3.省略号参数的本质是一个interface,用于接收任意类型的切片。
06:24可变参数函数的实现
1.可变参数函数通过for循环遍历切片中的每个元素,并进行相应的处理。 2.函数可以定义固定的参数和可变参数的组合,满足不同的需求。
-
重点
本视频暂不支持提取重点
一、函数 00:01
1. 函数的返回值 00:15
-
返回值灵活性:Go语言函数可以返回单值、多值或不返回值。例如初始化函数可能不需要返回值,无限循环函数也不需要返回值。
-
命名返回值:可以在函数定义时指定返回值的变量名,如func add(a,b int) (sum int, err error),这样在函数体内可以直接使用这些变量名而无需重新声明。
-
简化return:当使用命名返回值时,可以直接写return而不指定返回值,此时会自动返回已定义的命名返回值变量。
2. 函数的省略号 03:50
1)例题:打印变量示例 04:12
-
变长参数:Go语言中可以使用...语法定义变长参数,如fmt.Println可以接受任意数量的参数。
-
参数类型限制:变长参数必须为同一类型,如...int表示所有参数都必须是int类型。
2)源码解析 05:18
-
底层实现:变长参数本质上是一个切片,如...int在函数内部会被视为[]int类型。
-
interface{}应用:fmt.Println使用...any作为参数类型,any是interface{}的别名,可以接受任意类型参数。
3)例题:切片相加示例 06:21
-
变长参数处理:可以通过range遍历变长参数切片,如for _, value := range items来逐个处理参数。
-
混合参数:函数可以同时包含固定参数和变长参数,如func add(desc string, items ...int),其中desc是必传参数,items是可选的变长参数。
-
调试技巧:可以通过debug查看变长参数在内存中的实际存储形式,确认其切片特性。
二、知识小结
知识点 | 核心内容 | 易混淆点/注意事项 | 代码示例 |
---|---|---|---|
函数返回值 | 函数可返回单值、多值或不返回值(如初始化函数或无限循环函数) | 无返回值时需明确函数用途(如runForever示例) | go func runForever() { for { ... } } |
命名返回值 | 可在函数定义时声明返回变量名,直接赋值后通过return隐式返回 | 需前后变量名一致(如sum和err),避免重复定义 | go func add(a, b int) (sum int, err error) { sum = a + b; return } |
变长参数(省略号) | 通过...Type定义动态参数(如...int),实际接收为切片类型 | 需与固定参数区分(如describe string, nums ...int) | go func add(desc string, nums ...int) int { ... } |
参数严格性 | 静态语言需严格匹配参数数量,Go通过变长参数实现灵活性 | 变长参数必须为同一类型,且需通过切片操作处理 | go for _, v := range nums { sum += v } |
混合参数定义 | 支持固定参数+变长参数组合(如describe string, nums ...int) | 固定参数必须传,变长参数可选 | go add("结果:", 1, 2, 3) |
-
摘要
该视频主要讲述了函数作为一等公民的特性,即函数可以像变量一样被传递和赋值。通过示例展示了如何将函数赋值给变量并调用,以及函数返回函数的复杂用法。视频中特别强调了传递函数名而非调用结果,并展示了如何通过函数返回不同操作的函数,实现类似计算器的功能。最后,还提及了函数可以作为参数传递,展示了函数式编程的灵活性和强大功能。
-
分段总结
折叠
00:01函数作为一等公民的特性
1.函数可以当做变量传递,赋予变量后可以在代码中灵活调用。 2.函数传递时只需传递函数名,不能传递调用结果。 3.函数作为变量传递后,可以在调用时传入参数或返回值。
02:03函数返回函数
1.函数可以返回另一个函数,返回的函数可以接收参数并返回结果。 2.返回的函数可以定义在内部,不需要显式命名。 3.返回的函数可以在调用时接收参数,并执行相应的逻辑。
05:36函数作为参数传递
1.函数可以作为参数传递给其他函数,作为参数的函数可以接收参数并返回结果。 2.函数作为参数传递时,可以在调用时传入任意类型的函数。 3.函数作为参数传递可以增加代码的灵活性和可重用性。
09:26匿名函数
1.匿名函数是没有名称的函数,可以在代码中临时定义并使用。 2.匿名函数可以接收参数并返回结果,用于实现特定的逻辑。 3.匿名函数可以在调用时传递参数,并在函数内部使用这些参数。
-
重点
本视频暂不支持提取重点
一、函数的一等公民特性 00:00
-
特性定义
:Go语言中函数是"一等公民",具有三个核心特性:
-
函数本身可以当做变量
-
支持匿名函数和闭包
-
函数可以满足接口
-
1. 举例讲解函数作为变量 00:32
-
变量赋值:函数可以像普通变量一样被赋值,如funcVar := add,其中add是已定义的函数名
-
调用区别
:
-
传递函数名:funcVar := add(正确,传递的是函数本身)
-
传递调用结果:funcVar := add()(错误,传递的是函数返回值)
-
-
调用方式:通过变量名加参数列表调用,如funcVar(a,b,3,4)
2. 举例讲解函数作为返回值 02:00
-
返回函数:函数可以返回另一个函数,如cal函数根据操作符返回不同的匿名函数
-
匿名函数:返回的函数可以没有名称,直接定义函数体
-
调用链:需要两级调用才能执行返回的函数逻辑:
3. 举例讲解回调函数 09:40
-
回调定义:函数可以作为参数传递给其他函数,这种参数称为回调函数
-
实现方式:
-
匿名函数传递:可以直接传递匿名函数作为回调:
-
变量传递:也可以先将函数赋值给变量再传递:
-
实际应用
:这些特性在实际开发中非常常见,特别是在:
-
需要灵活改变行为时(通过回调)
-
需要延迟执行时(通过返回函数)
-
需要简化接口实现时(通过函数满足接口)
-
二、知识小结
知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
---|---|---|---|
函数的一等公民特性 | 函数可作为变量传递、参数或返回值,支持匿名函数定义 | 传递函数名(非调用结果)与匿名函数语法 | ⭐⭐ |
函数作为变量 | 将函数赋值给变量(如 funcVar = add),通过变量调用函数 | 变量存储的是函数引用,而非执行结果 | ⭐⭐ |
函数作为返回值 | 函数内部可返回另一个函数(如计算器案例返回加法/减法逻辑) | 需注意返回的函数需再次调用才能执行 | ⭐⭐⭐ |
函数作为参数 | 高阶函数接收函数参数(如 callback(y int, f func(int,int))) | 匿名函数需匹配参数和返回值类型 | ⭐⭐⭐ |
匿名函数应用 | 临时定义无名称函数(如 localFunc := func(a,b int) { ... }) | 闭包特性与作用域控制 | ⭐⭐⭐⭐ |
实际开发意义 | 代码灵活性提升(如回调机制、逻辑动态注入) | 生产环境中常见于中间件、策略模式等场景 | ⭐⭐⭐ |
-
摘要
该视频主要讲述了Go语言中的函数b包的特性,并通过实例演示了如何在函数中定义和使用局部变量,特别是如何通过匿名函数封装局部变量实现函数每次调用返回结果自动递增的效果。同时,视频还强调了函数间局部变量的不可访问性,以及如何在匿名函数中访问外部函数的局部变量。这些内容对于理解Go语言的函数特性和编程实践具有重要意义。
-
分段总结
折叠
00:01闭包特性概述
1.闭包特性对于许多编程初学者来说难以理解,因此采用问题导向的方式讲解。 2.通过一个需求引入闭包的概念,即创建一个函数,每次调用返回结果递增。
01:06普通函数实现
1.定义全局变量来跟踪计数器值,但这种方式迫使全局变量的使用,且无法轻易重置。 2.全局变量在函数外部可访问,可能导致意外的状态共享和竞争条件。
03:12闭包实现计数器
1.将计数器变量封装在函数内部,通过闭包特性返回匿名函数。 2.匿名函数可以访问外部函数的局部变量,实现计数器的递增。 3.闭包特性允许将函数及其内部状态一起返回,形成一种可调用的包装器。
06:09闭包执行过程
1.闭包函数在每次调用时执行内部逻辑,递增计数器变量。 2.闭包函数返回后,内部状态得以保留,下次调用时继续递增。 3.闭包函数的返回值是函数本身,而不是执行结果,需要显式调用。
09:38闭包特性总结
1.闭包特性解决了变量封装和状态管理的问题,使得函数内部状态可以持久化。 2.闭包函数可以随时归零并重新开始计数,提高了代码的灵活性和可重用性。
-
重点
本视频暂不支持提取重点
一、闭包特性 00:02
1. 问题引入 00:30
-
核心需求:创建一个函数,每次调用返回结果都比前一次调用结果大1
-
传统方案缺陷:使用全局变量会导致变量污染且无法重置状态
-
闭包优势:既能保持状态(类似全局变量),又能封装变量(避免污染)
2. 普通函数使用 01:03
-
实现方式:
-
局限性
:
-
变量暴露在全局作用域
-
无法实现状态重置(除非手动修改全局变量)
-
多goroutine环境下存在竞态风险
-
3. for循环函数调用 02:05
-
测试代码:
-
输出结果:1,2,3,4,5(证明全局变量方案能实现基本需求)
4. 函数中定义函数 03:14
-
关键改进:
-
闭包特性
:
-
内部函数可以访问外部函数的局部变量
-
变量生命周期与闭包绑定(非全局作用域)
-
每次调用外部函数会创建新的闭包环境
-
5. 问题展示 05:56
-
常见错误:
-
错误现象:每次调用都返回1(因为local每次都被重新初始化为0)
6. 函数执行过程分析 06:35
-
正确理解
:
-
外部函数只执行初始化(local := 0)
-
内部函数负责状态维护(local += 1)
-
必须返回函数引用而非立即执行结果
-
7. 返回函数指针 07:23
-
标准写法:
-
状态重置:重新调用auoIncrement()会创建新的闭包环境(local重新初始化为0)
8. 函数使用展示 08:16
-
完整示例:
-
优势总结
:
-
状态封装(避免全局变量污染)
-
独立环境(支持多实例)
-
灵活重置(通过新建闭包)
-
二、知识小结
知识点 |
---|