在这里插入图片描述

一、函数定义基础 🎯

1.1 基本语法结构

在仓颉语言中,函数使用 func 关键字定义。完整的函数定义包含以下几个部分:

func functionName(参数列表): 返回类型 {
    // 函数体
    return 返回值
}

核心组成部分:

  • func 关键字:声明这是一个函数
  • 函数名:遵循驼峰命名规范
  • 参数列表:用逗号分隔的参数声明
  • 返回类型:指定函数返回值的类型
  • 函数体:包含具体的执行逻辑

1.2 简单函数示例

// 计算两个数的和
func add(a: Int64, b: Int64): Int64 {
    return a + b
}

// 计算矩形面积
func calculateArea(width: Float64, height: Float64): Float64 {
    return width * height
}

// 判断是否为偶数
func isEven(number: Int64): Bool {
    return number % 2 == 0
}

1.3 无返回值函数

当函数不需要返回值时,使用 Unit 类型(类似其他语言的 void):

func printGreeting(name: String): Unit {
    println("欢迎你,${name}!👋")
}

func logMessage(message: String): Unit {
    println("[日志] ${message}")
}

二、参数详解 📋

2.1 基本参数

每个参数由参数名和类型组成:

func createProfile(username: String, age: Int64, email: String): Unit {
    println("用户名: ${username}")
    println("年龄: ${age}")
    println("邮箱: ${email}")
}

2.2 默认参数

默认参数允许在调用时省略某些参数:

func sendEmail(
    recipient: String, 
    subject: String = "无主题", 
    body: String = "无内容",
    priority: String = "普通"
): Unit {
    println("收件人: ${recipient}")
    println("主题: ${subject}")
    println("正文: ${body}")
    println("优先级: ${priority}")
}

// 调用方式
sendEmail("user@example.com")  // 使用所有默认值
sendEmail("user@example.com", "重要通知")  // 部分使用默认值
sendEmail("user@example.com", "会议提醒", "明天上午10点开会")

2.3 命名参数

命名参数提高代码可读性,允许以任意顺序传递参数:

func bookFlight(
    from: String,
    to: String,
    date: String,
    passengers: Int64,
    class: String = "经济舱"
): Unit {
    println("从 ${from} 到 ${to}")
    println("日期: ${date}")
    println("乘客数: ${passengers}")
    println("舱位: ${class}")
}

// 使用命名参数调用
bookFlight(
    to: "上海",
    from: "北京",
    passengers: 2,
    date: "2025-11-01",
    class: "商务舱"
)

2.4 可变参数

仓颉支持可变数量的参数(如果支持的话):

func sum(numbers: Array<Int64>): Int64 {
    var total: Int64 = 0
    for (num in numbers) {
        total += num
    }
    return total
}

// 调用
let result = sum([1, 2, 3, 4, 5])
println("总和: ${result}")  // 输出: 15

三、返回值处理 🔄

3.1 单返回值

func square(x: Int64): Int64 {
    return x * x
}

func getFullName(firstName: String, lastName: String): String {
    return "${firstName} ${lastName}"
}

3.2 多返回值(使用元组)

func divideWithRemainder(dividend: Int64, divisor: Int64): (Int64, Int64) {
    let quotient = dividend / divisor
    let remainder = dividend % divisor
    return (quotient, remainder)
}

// 使用
let (q, r) = divideWithRemainder(17, 5)
println("商: ${q}, 余数: ${r}")  // 商: 3, 余数: 2

3.3 提前返回

func checkAge(age: Int64): String {
    if (age < 0) {
        return "年龄无效"
    }
    if (age < 18) {
        return "未成年"
    }
    if (age < 60) {
        return "成年人"
    }
    return "老年人"
}

四、高阶函数 🚀

4.1 函数作为参数

高阶函数可以接受其他函数作为参数:

func applyOperation(
    a: Int64, 
    b: Int64, 
    operation: (Int64, Int64) -> Int64
): Int64 {
    return operation(a, b)
}

func add(x: Int64, y: Int64): Int64 {
    return x + y
}

func multiply(x: Int64, y: Int64): Int64 {
    return x * y
}

// 调用
let sum = applyOperation(10, 5, add)        // 15
let product = applyOperation(10, 5, multiply)  // 50

4.2 函数作为返回值

func getOperation(operationType: String): (Int64, Int64) -> Int64 {
    if (operationType == "add") {
        return add
    } else {
        return multiply
    }
}

// 使用
let operation = getOperation("add")
let result = operation(7, 3)  // 10

4.3 实用的高阶函数场景

// 过滤数组
func filter(numbers: Array<Int64>, predicate: (Int64) -> Bool): Array<Int64> {
    var result = Array<Int64>()
    for (num in numbers) {
        if (predicate(num)) {
            result.append(num)
        }
    }
    return result
}

func isPositive(x: Int64): Bool {
    return x > 0
}

let numbers = [-2, -1, 0, 1, 2, 3]
let positives = filter(numbers, isPositive)

五、Lambda 表达式与闭包 ✨

5.1 Lambda 基本语法

Lambda 表达式提供了简洁的匿名函数写法:

// 基本形式
let square = {x: Int64 => x * x}
println(square(5))  // 25

// 多参数 Lambda
let add = {x: Int64, y: Int64 => x + y}
println(add(3, 7))  // 10

// 复杂逻辑的 Lambda
let isEvenAndPositive = {x: Int64 => 
    x > 0 && x % 2 == 0
}

5.2 Lambda 在高阶函数中的应用

// 直接使用 Lambda 表达式
let result = applyOperation(8, 4, {x: Int64, y: Int64 => x - y})
println(result)  // 4

// 用于数组操作
let numbers = [1, 2, 3, 4, 5]
let doubled = numbers.map({x: Int64 => x * 2})
let evens = numbers.filter({x: Int64 => x % 2 == 0})

5.3 闭包特性

闭包可以捕获外部作用域的变量:

func makeMultiplier(factor: Int64): (Int64) -> Int64 {
    return {x: Int64 => x * factor}
}

let triple = makeMultiplier(3)
println(triple(5))   // 15
println(triple(10))  // 30

let double = makeMultiplier(2)
println(double(5))   // 10

六、函数重载 🔧

6.1 基于参数类型重载

func display(value: Int64): Unit {
    println("整数值: ${value}")
}

func display(value: Float64): Unit {
    println("浮点数值: ${value}")
}

func display(value: String): Unit {
    println("字符串值: ${value}")
}

func display(value: Bool): Unit {
    println("布尔值: ${value}")
}

// 调用时自动选择匹配的版本
display(42)           // 整数值: 42
display(3.14)         // 浮点数值: 3.14
display("Hello")      // 字符串值: Hello
display(true)         // 布尔值: true

6.2 基于参数数量重载

func greet(): Unit {
    println("你好!👋")
}

func greet(name: String): Unit {
    println("你好,${name}!👋")
}

func greet(firstName: String, lastName: String): Unit {
    println("你好,${firstName} ${lastName}!👋")
}

6.3 复杂重载示例

func calculate(x: Int64, y: Int64): Int64 {
    return x + y
}

func calculate(x: Float64, y: Float64): Float64 {
    return x + y
}

func calculate(x: Int64, y: Int64, z: Int64): Int64 {
    return x + y + z
}

七、递归函数 🔁

7.1 简单递归

// 计算阶乘
func factorial(n: Int64): Int64 {
    if (n <= 1) {
        return 1
    }
    return n * factorial(n - 1)
}

println(factorial(5))  // 120

7.2 尾递归优化

// 尾递归版本的阶乘
func factorialTail(n: Int64, accumulator: Int64 = 1): Int64 {
    if (n <= 1) {
        return accumulator
    }
    return factorialTail(n - 1, n * accumulator)
}

7.3 递归实例:斐波那契数列

func fibonacci(n: Int64): Int64 {
    if (n <= 1) {
        return n
    }
    return fibonacci(n - 1) + fibonacci(n - 2)
}

// 优化版本(使用记忆化)
func fibonacciOptimized(n: Int64, memo: MutMap<Int64, Int64> = MutMap<Int64, Int64>()): Int64 {
    if (n <= 1) {
        return n
    }
    if (memo.contains(n)) {
        return memo[n]
    }
    let result = fibonacciOptimized(n - 1, memo) + fibonacciOptimized(n - 2, memo)
    memo[n] = result
    return result
}

八、作用域与可见性 👁️

8.1 局部变量

func calculateDiscount(price: Float64, discountRate: Float64): Float64 {
    let discount = price * discountRate  // 局部变量
    let finalPrice = price - discount
    return finalPrice
}
// discount 和 finalPrice 只在函数内可见

8.2 嵌套函数

func outerFunction(x: Int64): Int64 {
    func innerFunction(y: Int64): Int64 {
        return x + y  // 可以访问外部函数的参数
    }
    
    return innerFunction(10)
}

println(outerFunction(5))  // 15

九、实用函数设计模式 💡

9.1 工厂函数

func createUser(name: String, age: Int64, role: String): User {
    return User(
        name: name,
        age: age,
        role: role,
        createdAt: getCurrentTime()
    )
}

9.2 辅助函数

func validateEmail(email: String): Bool {
    // 简化的邮箱验证逻辑
    return email.contains("@") && email.contains(".")
}

func validatePassword(password: String): Bool {
    return password.length() >= 8
}

func registerUser(email: String, password: String): Bool {
    if (!validateEmail(email)) {
        println("邮箱格式无效")
        return false
    }
    if (!validatePassword(password)) {
        println("密码长度不足")
        return false
    }
    println("注册成功!🎉")
    return true
}

9.3 链式调用

class StringBuilder {
    private var content: String = ""
    
    func append(text: String): StringBuilder {
        content += text
        return this
    }
    
    func appendLine(text: String): StringBuilder {
        content += text + "\n"
        return this
    }
    
    func build(): String {
        return content
    }
}

// 使用
let result = StringBuilder()
    .append("Hello")
    .append(" ")
    .append("World")
    .appendLine("!")
    .build()

十、最佳实践与技巧 ⭐

10.1 函数命名规范

// ✅ 好的命名
func calculateTotalPrice(items: Array<Item>): Float64 { }
func isUserLoggedIn(): Bool { }
func getUserById(id: Int64): User { }

// ❌ 不好的命名
func calc(x: Array<Item>): Float64 { }
func check(): Bool { }
func get(id: Int64): User { }

10.2 单一职责原则

// ✅ 职责清晰
func validateInput(input: String): Bool { }
func saveToDatabase(data: String): Unit { }
func sendNotification(user: User): Unit { }

// ❌ 职责混杂
func validateAndSaveAndNotify(input: String, user: User): Unit {
    // 做太多事情
}

10.3 参数数量控制

// ✅ 参数适中,使用对象封装
struct UserConfig {
    let name: String
    let age: Int64
    let email: String
    let phone: String
    let address: String
}

func createUser(config: UserConfig): User { }

// ❌ 参数过多
func createUser(name: String, age: Int64, email: String, 
                phone: String, address: String, 
                city: String, country: String): User { }

10.4 错误处理

func safeDivide(a: Int64, b: Int64): Option<Int64> {
    if (b == 0) {
        return None
    }
    return Some(a / b)
}

// 使用
match (safeDivide(10, 2)) {
    case Some(value) => println("结果: ${value}")
    case None => println("除数不能为零")
}

十一、性能优化建议 🚄

11.1 避免不必要的函数调用

// ✅ 优化版本
func processLargeArray(arr: Array<Int64>): Int64 {
    let size = arr.size()  // 只调用一次
    var sum: Int64 = 0
    for (i in 0..size) {
        sum += arr[i]
    }
    return sum
}

// ❌ 未优化版本
func processLargeArraySlow(arr: Array<Int64>): Int64 {
    var sum: Int64 = 0
    for (i in 0..arr.size()) {  // 每次循环都调用 size()
        sum += arr[i]
    }
    return sum
}

11.2 使用尾递归

// ✅ 尾递归,可以被优化
func sumTail(n: Int64, acc: Int64 = 0): Int64 {
    if (n == 0) return acc
    return sumTail(n - 1, acc + n)
}

// ❌ 非尾递归
func sumNormal(n: Int64): Int64 {
    if (n == 0) return 0
    return n + sumNormal(n - 1)
}

总结 🎓

仓颉语言的函数系统功能强大且灵活,主要特点包括:

清晰的语法:使用 func 关键字定义,结构清晰
类型安全:所有参数和返回值都有明确的类型
灵活的参数:支持默认参数、命名参数
函数式编程:支持高阶函数、Lambda 表达式、闭包
函数重载:基于参数类型和数量的重载机制
递归支持:包括尾递归优化
良好的封装:支持嵌套函数和作用域控制

掌握这些概念和技巧,你就能编写出高质量、可维护的仓颉代码!💪🌟

Logo

新一代开源开发者平台 GitCode,通过集成代码托管服务、代码仓库以及可信赖的开源组件库,让开发者可以在云端进行代码托管和开发。旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐