/* 01-basic-functions.go - Go 语言基础函数详解 学习目标: 1. 掌握函数的基本语法和定义 2. 理解函数参数和返回值 3. 学会函数的调用方式 4. 了解函数的作用域规则 5. 掌握函数的实际应用 知识点: - 函数定义语法 - 参数传递(值传递) - 返回值 - 函数调用 - 函数作为值 - 匿名函数 - 递归函数 - 函数作用域 */ package main import ( "fmt" "math" "strings" ) func main() { fmt.Println("=== Go 语言基础函数详解 ===\n") // 演示基本函数定义和调用 demonstrateBasicFunctions() // 演示函数参数 demonstrateFunctionParameters() // 演示函数返回值 demonstrateFunctionReturns() // 演示函数作为值 demonstrateFunctionAsValue() // 演示匿名函数 demonstrateAnonymousFunctions() // 演示递归函数 demonstrateRecursiveFunctions() // 演示函数作用域 demonstrateFunctionScope() // 演示实际应用示例 demonstratePracticalExamples() } // demonstrateBasicFunctions 演示基本函数定义和调用 func demonstrateBasicFunctions() { fmt.Println("1. 基本函数定义和调用:") // 调用无参数无返回值的函数 fmt.Printf(" 调用无参数无返回值的函数:\n") sayHello() // 调用有参数无返回值的函数 fmt.Printf(" 调用有参数无返回值的函数:\n") greetPerson("Alice") greetPerson("Bob") // 调用有参数有返回值的函数 fmt.Printf(" 调用有参数有返回值的函数:\n") result := add(10, 20) fmt.Printf(" add(10, 20) = %d\n", result) // 直接在表达式中使用函数调用 fmt.Printf(" add(5, 7) * 2 = %d\n", add(5, 7)*2) // 函数调用作为参数 fmt.Printf(" add(add(1, 2), add(3, 4)) = %d\n", add(add(1, 2), add(3, 4))) fmt.Println() } // demonstrateFunctionParameters 演示函数参数 func demonstrateFunctionParameters() { fmt.Println("2. 函数参数:") // 单个参数 fmt.Printf(" 单个参数:\n") square := calculateSquare(5) fmt.Printf(" calculateSquare(5) = %d\n", square) // 多个参数 fmt.Printf(" 多个参数:\n") area := calculateRectangleArea(4, 6) fmt.Printf(" calculateRectangleArea(4, 6) = %d\n", area) // 相同类型的多个参数 fmt.Printf(" 相同类型的多个参数:\n") max := findMax(15, 8, 23, 4, 19) fmt.Printf(" findMax(15, 8, 23, 4, 19) = %d\n", max) // 不同类型的参数 fmt.Printf(" 不同类型的参数:\n") info := formatPersonInfo("Charlie", 25, 175.5) fmt.Printf(" %s\n", info) // 参数是值传递 fmt.Printf(" 参数是值传递(不会修改原变量):\n") x := 10 fmt.Printf(" 修改前: x = %d\n", x) tryToModify(x) fmt.Printf(" 修改后: x = %d (未改变)\n", x) // 传递切片(引用类型) fmt.Printf(" 传递切片(引用类型):\n") numbers := []int{1, 2, 3, 4, 5} fmt.Printf(" 修改前: %v\n", numbers) modifySlice(numbers) fmt.Printf(" 修改后: %v (已改变)\n", numbers) fmt.Println() } // demonstrateFunctionReturns 演示函数返回值 func demonstrateFunctionReturns() { fmt.Println("3. 函数返回值:") // 单个返回值 fmt.Printf(" 单个返回值:\n") length := getStringLength("Hello, World!") fmt.Printf(" 字符串长度: %d\n", length) // 多个返回值 fmt.Printf(" 多个返回值:\n") quotient, remainder := divide(17, 5) fmt.Printf(" 17 ÷ 5 = %d 余 %d\n", quotient, remainder) // 命名返回值 fmt.Printf(" 命名返回值:\n") min, max := findMinMax([]int{3, 7, 1, 9, 4, 6}) fmt.Printf(" 数组 [3, 7, 1, 9, 4, 6] 的最小值: %d, 最大值: %d\n", min, max) // 忽略某些返回值 fmt.Printf(" 忽略某些返回值:\n") _, rem := divide(20, 3) fmt.Printf(" 20 ÷ 3 的余数: %d\n", rem) // 返回函数 fmt.Printf(" 返回函数:\n") multiplier := getMultiplier(3) result := multiplier(10) fmt.Printf(" 3倍数函数应用于10: %d\n", result) fmt.Println() } // demonstrateFunctionAsValue 演示函数作为值 func demonstrateFunctionAsValue() { fmt.Println("4. 函数作为值:") // 将函数赋值给变量 fmt.Printf(" 将函数赋值给变量:\n") var operation func(int, int) int operation = add fmt.Printf(" operation = add; operation(5, 3) = %d\n", operation(5, 3)) operation = multiply fmt.Printf(" operation = multiply; operation(5, 3) = %d\n", operation(5, 3)) // 函数作为参数 fmt.Printf(" 函数作为参数:\n") numbers := []int{1, 2, 3, 4, 5} result1 := applyOperation(numbers, double) fmt.Printf(" 应用 double 函数: %v -> %v\n", numbers, result1) result2 := applyOperation(numbers, square) fmt.Printf(" 应用 square 函数: %v -> %v\n", numbers, result2) // 函数切片 fmt.Printf(" 函数切片:\n") operations := []func(int, int) int{add, subtract, multiply} operationNames := []string{"加法", "减法", "乘法"} a, b := 12, 4 for i, op := range operations { result := op(a, b) fmt.Printf(" %s: %d %s %d = %d\n", operationNames[i], a, getOperatorSymbol(i), b, result) } fmt.Println() } // demonstrateAnonymousFunctions 演示匿名函数 func demonstrateAnonymousFunctions() { fmt.Println("5. 匿名函数:") // 基本匿名函数 fmt.Printf(" 基本匿名函数:\n") result := func(x, y int) int { return x*x + y*y }(3, 4) fmt.Printf(" 匿名函数计算 3² + 4² = %d\n", result) // 将匿名函数赋值给变量 fmt.Printf(" 将匿名函数赋值给变量:\n") isEven := func(n int) bool { return n%2 == 0 } for i := 1; i <= 5; i++ { fmt.Printf(" %d 是偶数: %t\n", i, isEven(i)) } // 匿名函数作为参数 fmt.Printf(" 匿名函数作为参数:\n") numbers := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} evenNumbers := filter(numbers, func(n int) bool { return n%2 == 0 }) fmt.Printf(" 偶数: %v\n", evenNumbers) largeNumbers := filter(numbers, func(n int) bool { return n > 5 }) fmt.Printf(" 大于5的数: %v\n", largeNumbers) // 匿名函数闭包 fmt.Printf(" 匿名函数闭包:\n") counter := func() func() int { count := 0 return func() int { count++ return count } }() fmt.Printf(" 计数器调用1: %d\n", counter()) fmt.Printf(" 计数器调用2: %d\n", counter()) fmt.Printf(" 计数器调用3: %d\n", counter()) fmt.Println() } // demonstrateRecursiveFunctions 演示递归函数 func demonstrateRecursiveFunctions() { fmt.Println("6. 递归函数:") // 阶乘函数 fmt.Printf(" 阶乘函数:\n") for i := 0; i <= 5; i++ { fact := factorial(i) fmt.Printf(" %d! = %d\n", i, fact) } // 斐波那契数列 fmt.Printf(" 斐波那契数列:\n") fmt.Printf(" 前10个斐波那契数: ") for i := 0; i < 10; i++ { fmt.Printf("%d ", fibonacci(i)) } fmt.Printf("\n") // 二分查找 fmt.Printf(" 二分查找:\n") sortedArray := []int{1, 3, 5, 7, 9, 11, 13, 15, 17, 19} target := 7 index := binarySearch(sortedArray, target, 0, len(sortedArray)-1) if index != -1 { fmt.Printf(" 在数组 %v 中找到 %d,索引: %d\n", sortedArray, target, index) } else { fmt.Printf(" 在数组 %v 中未找到 %d\n", sortedArray, target) } // 计算数字各位数之和 fmt.Printf(" 计算数字各位数之和:\n") number := 12345 digitSum := sumOfDigits(number) fmt.Printf(" %d 的各位数之和: %d\n", number, digitSum) fmt.Println() } // demonstrateFunctionScope 演示函数作用域 func demonstrateFunctionScope() { fmt.Println("7. 函数作用域:") // 全局变量 fmt.Printf(" 全局变量: globalVar = %s\n", globalVar) // 局部变量 fmt.Printf(" 局部变量:\n") localVar := "这是局部变量" fmt.Printf(" localVar = %s\n", localVar) // 函数内部的作用域 fmt.Printf(" 函数内部的作用域:\n") testScope() // 参数作用域 fmt.Printf(" 参数作用域:\n") testParameterScope("参数值") // 变量遮蔽 fmt.Printf(" 变量遮蔽:\n") testVariableShadowing() fmt.Println() } // demonstratePracticalExamples 演示实际应用示例 func demonstratePracticalExamples() { fmt.Println("8. 实际应用示例:") // 示例1: 数据处理函数 fmt.Printf(" 示例1 - 学生成绩处理:\n") scores := []int{85, 92, 78, 96, 88, 73, 91, 87} avg := calculateAverage(scores) fmt.Printf(" 平均分: %.2f\n", avg) grade := getLetterGrade(avg) fmt.Printf(" 等级: %s\n", grade) passCount := countPassingScores(scores, 80) fmt.Printf(" 80分以上人数: %d/%d\n", passCount, len(scores)) // 示例2: 字符串处理函数 fmt.Printf(" 示例2 - 文本处理:\n") text := "Hello, World! This is a test." wordCount := countWords(text) fmt.Printf(" 文本: \"%s\"\n", text) fmt.Printf(" 单词数: %d\n", wordCount) reversed := reverseString(text) fmt.Printf(" 反转: \"%s\"\n", reversed) isPalindrome := checkPalindrome("racecar") fmt.Printf(" \"racecar\" 是回文: %t\n", isPalindrome) // 示例3: 数学计算函数 fmt.Printf(" 示例3 - 几何计算:\n") circleArea := calculateCircleArea(5.0) fmt.Printf(" 半径5的圆面积: %.2f\n", circleArea) triangleArea := calculateTriangleArea(3.0, 4.0, 5.0) fmt.Printf(" 边长3,4,5的三角形面积: %.2f\n", triangleArea) distance := calculateDistance(0, 0, 3, 4) fmt.Printf(" 点(0,0)到点(3,4)的距离: %.2f\n", distance) // 示例4: 数据验证函数 fmt.Printf(" 示例4 - 数据验证:\n") emails := []string{ "user@example.com", "invalid-email", "test@domain.org", } for _, email := range emails { isValid := validateEmail(email) fmt.Printf(" 邮箱 \"%s\" 有效: %t\n", email, isValid) } phone := "138-1234-5678" isValidPhone := validatePhoneNumber(phone) fmt.Printf(" 电话 \"%s\" 有效: %t\n", phone, isValidPhone) fmt.Println() } // ========== 函数定义 ========== // 全局变量 var globalVar = "全局变量" // 无参数无返回值的函数 func sayHello() { fmt.Printf(" Hello, World!\n") } // 有参数无返回值的函数 func greetPerson(name string) { fmt.Printf(" Hello, %s!\n", name) } // 有参数有返回值的函数 func add(a, b int) int { return a + b } // 单个参数函数 func calculateSquare(n int) int { return n * n } // 多个参数函数 func calculateRectangleArea(width, height int) int { return width * height } // 相同类型多个参数函数 func findMax(numbers ...int) int { if len(numbers) == 0 { return 0 } max := numbers[0] for _, num := range numbers { if num > max { max = num } } return max } // 不同类型参数函数 func formatPersonInfo(name string, age int, height float64) string { return fmt.Sprintf("姓名: %s, 年龄: %d, 身高: %.1fcm", name, age, height) } // 尝试修改参数(值传递) func tryToModify(x int) { x = 100 fmt.Printf(" 函数内部: x = %d\n", x) } // 修改切片 func modifySlice(slice []int) { if len(slice) > 0 { slice[0] = 999 } } // 单个返回值函数 func getStringLength(s string) int { return len(s) } // 多个返回值函数 func divide(a, b int) (int, int) { return a / b, a % b } // 命名返回值函数 func findMinMax(numbers []int) (min, max int) { if len(numbers) == 0 { return 0, 0 } min, max = numbers[0], numbers[0] for _, num := range numbers { if num < min { min = num } if num > max { max = num } } return // 自动返回命名的返回值 } // 返回函数的函数 func getMultiplier(factor int) func(int) int { return func(x int) int { return x * factor } } // 基本运算函数 func multiply(a, b int) int { return a * b } func subtract(a, b int) int { return a - b } // 应用操作函数 func applyOperation(numbers []int, operation func(int) int) []int { result := make([]int, len(numbers)) for i, num := range numbers { result[i] = operation(num) } return result } // 操作函数 func double(x int) int { return x * 2 } func square(x int) int { return x * x } // 获取运算符符号 func getOperatorSymbol(index int) string { symbols := []string{"+", "-", "×"} if index < len(symbols) { return symbols[index] } return "?" } // 过滤函数 func filter(numbers []int, predicate func(int) bool) []int { var result []int for _, num := range numbers { if predicate(num) { result = append(result, num) } } return result } // 递归函数:阶乘 func factorial(n int) int { if n <= 1 { return 1 } return n * factorial(n-1) } // 递归函数:斐波那契 func fibonacci(n int) int { if n <= 1 { return n } return fibonacci(n-1) + fibonacci(n-2) } // 递归函数:二分查找 func binarySearch(arr []int, target, left, right int) int { if left > right { return -1 } mid := (left + right) / 2 if arr[mid] == target { return mid } else if arr[mid] > target { return binarySearch(arr, target, left, mid-1) } else { return binarySearch(arr, target, mid+1, right) } } // 递归函数:数字各位数之和 func sumOfDigits(n int) int { if n < 10 { return n } return n%10 + sumOfDigits(n/10) } // 作用域测试函数 func testScope() { innerVar := "函数内部变量" fmt.Printf(" innerVar = %s\n", innerVar) if true { blockVar := "块级变量" fmt.Printf(" blockVar = %s\n", blockVar) } // blockVar 在这里不可访问 } func testParameterScope(param string) { fmt.Printf(" 参数 param = %s\n", param) param = "修改后的参数" fmt.Printf(" 修改后 param = %s\n", param) } func testVariableShadowing() { x := "外层变量" fmt.Printf(" 外层 x = %s\n", x) if true { x := "内层变量" // 遮蔽外层变量 fmt.Printf(" 内层 x = %s\n", x) } fmt.Printf(" 外层 x = %s (未被修改)\n", x) } // 实际应用函数 func calculateAverage(scores []int) float64 { if len(scores) == 0 { return 0 } sum := 0 for _, score := range scores { sum += score } return float64(sum) / float64(len(scores)) } func getLetterGrade(average float64) string { switch { case average >= 90: return "A" case average >= 80: return "B" case average >= 70: return "C" case average >= 60: return "D" default: return "F" } } func countPassingScores(scores []int, threshold int) int { count := 0 for _, score := range scores { if score >= threshold { count++ } } return count } func countWords(text string) int { words := strings.Fields(text) return len(words) } func reverseString(s string) string { runes := []rune(s) for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 { runes[i], runes[j] = runes[j], runes[i] } return string(runes) } func checkPalindrome(s string) bool { s = strings.ToLower(s) for i, j := 0, len(s)-1; i < j; i, j = i+1, j-1 { if s[i] != s[j] { return false } } return true } func calculateCircleArea(radius float64) float64 { return math.Pi * radius * radius } func calculateTriangleArea(a, b, c float64) float64 { // 使用海伦公式 s := (a + b + c) / 2 return math.Sqrt(s * (s - a) * (s - b) * (s - c)) } func calculateDistance(x1, y1, x2, y2 float64) float64 { dx := x2 - x1 dy := y2 - y1 return math.Sqrt(dx*dx + dy*dy) } func validateEmail(email string) bool { return strings.Contains(email, "@") && strings.Contains(email, ".") } func validatePhoneNumber(phone string) bool { // 简单验证:包含数字和连字符 return strings.Contains(phone, "-") && len(phone) >= 10 } /* 运行这个程序: go run 01-basic-functions.go 学习要点: 1. 函数是 Go 程序的基本构建块 2. 函数定义语法:func 函数名(参数列表) 返回类型 { 函数体 } 3. Go 支持多返回值,这是其特色功能之一 4. 参数传递是值传递,但引用类型(切片、映射等)传递的是引用 5. 函数可以作为值传递和赋值 6. 支持匿名函数和闭包 7. 递归函数需要有明确的终止条件 函数的组成部分: 1. func 关键字 2. 函数名 3. 参数列表(可选) 4. 返回类型(可选) 5. 函数体 函数特性: 1. 支持多返回值 2. 支持命名返回值 3. 函数是一等公民(可以作为值) 4. 支持匿名函数和闭包 5. 支持递归调用 最佳实践: 1. 函数名应该清晰表达功能 2. 保持函数简短和专注 3. 合理使用多返回值 4. 适当使用命名返回值提高可读性 5. 避免过深的递归调用 6. 考虑函数的副作用 常见应用场景: 1. 代码复用和模块化 2. 数据处理和计算 3. 输入验证和格式化 4. 算法实现 5. 业务逻辑封装 6. 工具函数库 */