Go语言学习系列——基本函数定义与调用——【坚果派
1、基本函数定义与调用
代码语言:javascript代码运行次数:0运行复制package main
import "fmt"
// 1. 基本函数定义
func sayHello(name string) {
fmt.Printf("你好, %s!\n", name)
}
// 2. 带返回值的函数
func add(a, b int) int {
return a + b
}
// 3. 多返回值函数
func divide(a, b float64) (float64, error) {
if b == 0 {
return 0, fmt.Errorf("除数不能为0")
}
return a / b, nil
}
// 4. 命名返回值
func rectangle(width, height float64) (area, perimeter float64) {
area = width * height
perimeter = 2 * (width + height)
return // 隐式返回命名的返回值
}
func main() {
// 函数调用示例
sayHello("张三")
result := add(5, 3)
fmt.Printf("5 + 3 = %d\n", result)
if quotient, err := divide(10, 2); err != nil {
fmt.Println("错误:", err)
} else {
fmt.Printf("10 / 2 = %.2f\n", quotient)
}
area, peri := rectangle(4, 5)
fmt.Printf("矩形面积: %.2f, 周长: %.2f\n", area, peri)
}
2、函数作用域与变量
代码语言:javascript代码运行次数:0运行复制package main
import "fmt"
// 全局变量
var globalVar = "全局变量"
func main() {
// 局部变量
localVar := "局部变量"
fmt.Println("在main中访问:", globalVar)
fmt.Println("在main中访问:", localVar)
// 演示变量作用域
scopeDemo()
// 闭包示例
counter := createCounter()
fmt.Println(counter()) // 输出: 1
fmt.Println(counter()) // 输出: 2
fmt.Println(counter()) // 输出: 3
}
func scopeDemo() {
fmt.Println("在scopeDemo中访问:", globalVar)
// fmt.Println(localVar) // 错误:无法访问main的局部变量
}
// 闭包函数
func createCounter() func() int {
count := 0
return func() int {
count++
return count
}
}
3、递归函数示例
代码语言:javascript代码运行次数:0运行复制package main
import "fmt"
// 1. 阶乘计算
func factorial(n int) int {
if n <= 1 {
return 1
}
return n * factorial(n-1)
}
// 2. 斐波那契数列
func fibonacci(n int) int {
if n <= 1 {
return n
}
return fibonacci(n-1) + fibonacci(n-2)
}
// 3. 目录遍历示例
type TreeNode struct {
Value int
Left *TreeNode
Right *TreeNode
}
func traverseTree(node *TreeNode) {
if node == nil {
return
}
fmt.Printf("%d ", node.Value)
traverseTree(node.Left)
traverseTree(node.Right)
}
func main() {
// 测试阶乘
fmt.Println("5的阶乘:", factorial(5))
// 测试斐波那契
fmt.Println("\n斐波那契数列前10个数:")
for i := 0; i < 10; i++ {
fmt.Printf("%d ", fibonacci(i))
}
// 测试树遍历
fmt.Println("\n\n二叉树遍历:")
root := &TreeNode{
Value: 1,
Left: &TreeNode{
Value: 2,
Left: &TreeNode{Value: 4},
Right: &TreeNode{Value: 5},
},
Right: &TreeNode{
Value: 3,
Left: &TreeNode{Value: 6},
Right: &TreeNode{Value: 7},
},
}
traverseTree(root)
fmt.Println("\n\n按回车键退出...")
fmt.Scanln()
}
总结
1. 函数定义规则:
- 使用func关键字
- 函数名遵循可见性规则
- 参数列表可以为空
- 返回值类型可以省略
- 支持多返回值
2. 参数传递:
- 值传递:参数为副本
- 指针传递:可修改原值
- 可变参数:func(args ...type)
3. 作用域规则:
- 全局变量:包级别可见
- 局部变量:函数内可见
- 块级作用域:{}内可见
4. 闭包特点:
- 可以访问外部变量
- 保持外部变量状态
- 常用于回调函数
- 实现数据封装
5. 递归注意事项:
- 必须有终止条件
- 注意栈溢出风险
- 考虑性能影响
- 可以用循环优化
6. 最佳实践:
- 函数设计:
- 单一职责
- 适当长度
- 清晰的参数和返回值
- 良好的错误处理
- 变量作用域:
- 最小作用域原则
- 避免全局变量
- 合理使用包级变量
- 递归使用:
- 适合树形结构
- 考虑性能要求
- 提供非递归替代方案
章节 | 主题 | 内容 |
---|---|---|
第一部分:Go 语言入门 | Go 语言简介 | Go 语言的起源与发展 Go 语言的特点和应用场景 |
开发环境搭建 | 安装 Go 语言开发包(Golang) 配置开发环境变量 选择 IDE / 编辑器(如 VS Code、GoLand) | |
第一个 Go 程序 | 编写 "Hello, World!" 理解程序结构和执行流程 使用 go run 和 go build | |
第二部分:基础语法 | 变量和数据类型 | 变量声明与初始化 基本数据类型(整数、浮点数、布尔值、字符串) 类型转换与推断 |
常量 | 常量定义与使用 iota 枚举原理与应用 | |
运算符 | 算术、逻辑、比较运算符 运算符优先级与结合性 | |
控制结构 | 条件语句(if-else、switch) 循环语句(for、for-range) 跳转语句(break、continue、goto) | |
第三部分:函数 | 函数定义与调用 | 函数语法与参数传递 多返回值 作用域(全局变量 vs 局部变量) |
高级函数特性 | 闭包概念与使用 递归函数原理、实现与注意事项 | |
第四部分:数组、切片和映射 | 数组 | 数组定义、初始化与遍历 多维数组 |
切片 | 切片概念与创建方式 动态扩容机制 常用操作(追加、删除、复制) | |
映射(Map) | 映射定义、初始化与基本操作(增删查) 遍历与排序 | |
第五部分:结构体和方法 | 结构体 | 结构体定义与使用 嵌套与组合 |
方法与接口 | 方法定义与接收器(值 vs 指针) 接口定义、实现与多态性 | |
第六部分:错误处理和异常 | 错误处理 | error 类型机制 自定义错误与处理函数 |
异常处理 | panic 与 recover 使用 异常处理最佳实践 | |
第七部分:并发编程 | Go 协程(Goroutine) | 协程概念与创建方式 并发执行与调度 |
通道(Channel) | 通道定义与使用 同步与通信机制 缓冲通道与无缓冲通道 | |
并发模式与同步原语 | 生产者 - 消费者模式 扇入 / 扇出模式 sync 包(互斥锁、WaitGroup) | |
第八部分:文件操作和输入输出 | 文件操作 | 文件打开、读写、关闭 创建、删除与重命名 |
输入输出 | 标准输入输出(fmt 包) 格式化处理与字符串操作 | |
第九部分:测试和调试 | 单元测试 | testing 包使用 测试覆盖率概念与计算 |
调试技巧 | 使用 gdb 或 IDE 调试功能 日志记录与调试信息输出 | |
第十部分:项目实践 | 小型项目实践 | 实现命令行工具 开发简单 Web 服务器 |
项目结构与管理 | 目录结构组织 go mod 依赖管理 |