重学仓颉-4函数系统完全指南

引言

仓颉编程语言作为一门现代化的编程语言,其函数系统设计既保持了简洁性,又提供了强大的功能。本文将深入探讨仓颉语言中函数的所有特性,从基础定义到高级用法,为开发者提供全面的函数编程指南。

1. 函数定义基础

1.1 基本语法

仓颉使用关键字 func 来定义函数,基本语法结构如下:

cangjie 复制代码
func 函数名(参数列表): 返回类型 {
    函数体
}

基本函数定义示例:

cangjie 复制代码
func add(a: Int64, b: Int64): Int64 {
    return a + b
}

func greet(name: String): Unit {
    println("Hello, ${name}!")
}

func getMax(a: Int64, b: Int64) {
    if (a > b) {
        a
    } else {
        b
    }
}

1.2 参数类型详解

仓颉语言支持两种参数类型:非命名参数命名参数

非命名参数

  • 语法:参数名: 类型
  • 调用时必须按顺序传递参数
cangjie 复制代码
func calculate(a: Int64, b: Int64, c: Int64): Int64 {
    return a * b + c
}

// 调用方式
let result = calculate(2, 3, 4) // 必须按顺序:a=2, b=3, c=4

命名参数

  • 语法:参数名!: 类型
  • 调用时可以使用参数名指定值
  • 支持默认值设置
cangjie 复制代码
func createUser(name!: String, age!: Int64 = 18, email!: String = "") {
    println("User: ${name}, Age: ${age}, Email: ${email}")
}

main() {
    // 调用方式
    createUser(name: "张三", age: 25) // 使用默认email
    createUser(name: "李四", email: "li@example.com") // 使用默认age
    createUser(age: 30, name: "王五") // 参数顺序可以调换
}

重要规则:

  • 非命名参数必须在命名参数之前
  • 只有命名参数可以设置默认值
cangjie 复制代码
// 正确的定义
func valid(a: Int64, b: Int64, c!: Int64 = 0) {}

// 错误的定义 - 命名参数在非命名参数之前
func invalid(a!: Int64, b: Int64) {} // 编译错误

1.3 返回值类型

显式返回类型

cangjie 复制代码
func explicitReturn(): String {
    return "Hello World"
}

func mathOperation(a: Int64, b: Int64): (Int64, Int64) {
    return (a + b, a * b)
}

隐式返回类型推导

cangjie 复制代码
func inferredReturn(a: Int64, b: Int64) {
    a + b  // 编译器推导返回类型为 Int64
}

func voidFunction() {
    println("No return value")  // 编译器推导返回类型为 Unit
}

特殊规则:

  • 指定返回类型为 Unit 时,编译器会自动在所有返回点插入 return ()
  • 函数体类型由最后一个表达式的类型决定
cangjie 复制代码
func autoUnit(): Unit {
    if (true) {
        println("Hello")
        // 编译器自动插入 return ()
    }
    // 编译器自动插入 return ()
}

2. 函数调用详解

2.1 基本调用语法

cangjie 复制代码
func add(a: Int64, b!: Int64): Int64 {
    return a + b
}

func multiply(a!: Int64, b!: Int64): Int64 {
    return a * b
}

main() {
    let x = 10
    let y = 20
    // 命名参数调用
    let product = multiply(a: x, b: y)
    
    // 混合调用(非命名参数 + 命名参数)
    let sum = add(x, b: y)
    
    println("Sum: ${sum}, Product: ${product}")
}

2.2 默认参数值的使用

cangjie 复制代码
func createProfile(name!: String, age!: Int64 = 18, city!: String = "北京") {
    println("姓名: ${name}, 年龄: ${age}, 城市: ${city}")
}

main() {
    // 使用所有默认值
    createProfile(name: "张三")
    
    // 部分使用默认值
    createProfile(name: "李四", age: 25)
    
    // 覆盖所有默认值
    createProfile(name: "王五", age: 30, city: "上海")
}

2.3 变长参数

仓颉支持变长参数,但只能用于最后一个非命名参数:

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

func formatMessage(prefix: String, messages: Array<String>): String {
    var result = prefix + ": "
    for (msg in messages) {
        result += msg + " "
    }
    return result
}

main() {
    // 变长参数调用
    println(sum()) // 输出: 0
    println(sum(1, 2, 3, 4, 5)) // 输出: 15
    // 也可以作为一个整体传入。作为一个整体时是Array类型
    println(sum([1, 2, 3, 4, 5])) // 输出: 15

    println(formatMessage("INFO", "Hello", "World", "!")) // 输出: INFO: Hello World !
    // 同样也可以作为一个整体
    println(formatMessage("INFO", ["Hello", "World", "!"])) // 输出: INFO: Hello World !
}

3. 函数类型与一等公民

3.1 函数类型定义

仓颉中函数是一等公民,函数本身也有类型:

cangjie 复制代码
main(): Unit {
    // 函数类型语法: (参数类型) -> 返回类型
    let noParamFunc: () -> Unit = {=> println("Hello")}
    let intFunc: (Int64) -> Int64 = {x => x * 2}
    let multiParamFunc: (Int64, String) -> Bool = {num, str => num > 0}
    let complexFunc: ((Int64) -> Int64) -> Int64 = {f => f(10)}
}

3.2 函数作为参数

cangjie 复制代码
func applyOperation(a: Int64, b: Int64, op: (Int64, Int64) -> Int64): Int64 {
    return op(a, b)
}

func add(a: Int64, b: Int64): Int64 {
    a + b
}

func multiply(a: Int64, b: Int64): Int64 {
    a * b
}

func max(a: Int64, b: Int64): Int64 {
    if (a > b) {
        a
    } else {
        b
    }
}

main() {
    let x = 10
    let y = 5

    println(applyOperation(x, y, add)) // 输出: 15
    println(applyOperation(x, y, multiply)) // 输出: 50
    println(applyOperation(x, y, max)) // 输出: 10
}

3.3 函数作为返回值

cangjie 复制代码
func createCalculator(operation: String): (Int64, Int64) -> Int64 {
    if (operation == "add") {
        return {a, b => a + b}
    } else if (operation == "multiply") {
        return {a, b => a * b}
    } else {
        return {a, b => a - b}
    }
}

main() {
    let addFunc = createCalculator("add")
    let multiplyFunc = createCalculator("multiply")

    println(addFunc(5, 3)) // 输出: 8
    println(multiplyFunc(5, 3)) // 输出: 15
}

3.4 函数类型参数名

cangjie 复制代码
func processData(handler: (name: String, value: Int64) -> Unit) {
    handler("测试", 100)
}

main() {
    let dataHandler: (name: String, value: Int64) -> Unit = {
        name, value => println("处理数据: ${name} = ${value}")
    }

    processData(dataHandler)
}

4. Lambda 表达式

4.1 基本语法

Lambda 表达式是匿名函数的简洁写法:

cangjie 复制代码
// 基本语法: { 参数列表 => 表达式 }
let add = {a: Int64, b: Int64 => a + b}
let greet = {name: String => "Hello, ${name}!"}
let noParam = {=> "Hello World"}

main() {
    println(add(5, 3)) // 输出: 8
    println(greet("张三")) // 输出: Hello, 张三!
    println(noParam()) // 输出: Hello World
}

4.2 类型推导

cangjie 复制代码
// 从变量类型推导
let intHandler: (Int64) -> Int64 = {x => x * 2}

// 从函数参数类型推导
func processInt(handler: (Int64) -> Int64): Int64 {
    return handler(10)
}

main() {
    // 参数类型自动推导为 (Int64) -> Int64
    let result = processInt({x => x + 5})
    println(result) // 输出: 15
}

4.3 立即调用

cangjie 复制代码
main() {
    // 定义后立即调用
    let result1 = {a: Int64, b: Int64 => a * b}(4, 5)
    let result2 = {=> "立即执行"}()

    println(result1) // 输出: 20
    println(result2) // 输出: 立即执行
}

5. 闭包与变量捕获

5.1 闭包基本概念

闭包是函数或 lambda 从定义它的静态作用域中捕获变量的机制:

cangjie 复制代码
// func createCounter1(): () -> Int64 {
//     var count = 0

//     func increment():Int64 {
//         count++
//         count
//     }
//     // 如果捕获了可变变量的函数,必须立即被调用
//     // function capturing mutable variables needs to be called directly
//     return increment
// }

func createCounter(): () -> Int64 {
    let count = Box(0)

    func increment():Int64 {
        count.value++
        count.value
    }
    // 可以改为捕获常量,常量通过Box包装原始的简单值
    return increment
}

main() {
    let counter = createCounter()

    println(counter()) // 输出: 1
    println(counter()) // 输出: 2
    println(counter()) // 输出: 3
}

5.2 变量捕获规则

cangjie 复制代码
func createMultiplier(factor: Int64): (Int64) -> Int64 {
    // 捕获外部函数的参数 factor
    return { x => x * factor }
}

func createAdder(): (Int64) -> Int64 {
    let base = 100
    
    // 捕获局部变量 base
    func add(x: Int64) {
        return x + base
    }
    
    return add
}

main() {
    let double = createMultiplier(2)
    let add100 = createAdder()
    
    println(double(5))  // 输出: 10
    println(add100(5))  // 输出: 105
}

5.3 捕获限制

cangjie 复制代码
func demonstrateCapture() {
    var mutableVar = 1
    let immutableVar = 2
    
    // 捕获 var 变量的闭包不能作为一等公民使用
    func badClosure() {
        mutableVar++
    }
    
    // 只能调用,不能赋值给变量
    badClosure() // OK
    
    // 以下操作都会编译错误
    // let f = badClosure        // 错误
    // return badClosure         // 错误
    
    // 捕获 let 变量的闭包可以作为一等公民
    func goodClosure() {
        println(immutableVar)
    }
    
    let f = goodClosure // OK
    return goodClosure  // OK
}

6. 嵌套函数

6.1 基本用法

cangjie 复制代码
func outerFunction(x: Int64) {
    let outerVar = x * 2
    
    func innerFunction(y: Int64): Int64 {
        // 可以访问外部函数的变量和参数
        return outerVar + y
    }
    
    func anotherInner(z: Int64): Int64 {
        // 可以调用同级的嵌套函数
        return innerFunction(z) * 2
    }
    
    let result1 = innerFunction(10)
    let result2 = anotherInner(5)
    
    println("Result1: ${result1}, Result2: ${result2}")
}

main() {
    outerFunction(5)
}

6.2 返回嵌套函数

cangjie 复制代码
func createCalculator(): (Int64, Int64) -> Int64 {
    func add(a: Int64, b: Int64): Int64 {
        return a + b
    }
    
    func multiply(a: Int64, b: Int64): Int64 {
        return a * b
    }
    
    // 返回嵌套函数
    return add
}

func createMultiFunction(): (Int64) -> (Int64) -> Int64 {
    func createAdder(base: Int64): (Int64) -> Int64 {
        func add(x: Int64): Int64 {
            return base + x
        }
        return add
    }
    
    return createAdder
}

main() {
    let calc = createCalculator()
    println(calc(3, 4)) // 输出: 7
    
    let multiFunc = createMultiFunction()
    let add5 = multiFunc(5)
    println(add5(3)) // 输出: 8
}

7. 函数重载

7.1 基本重载规则

cangjie 复制代码
// 参数个数不同
func process(a: Int64): String {
    return "单个整数: ${a}"
}

func process(a: Int64, b: Int64): String {
    return "两个整数: ${a}, ${b}"
}

// 参数类型不同
func process(a: String): String {
    return "字符串: ${a}"
}

func process(a: Float64): String {
    return "浮点数: ${a}"
}

// 泛型函数重载
func process<T>(a: T): String where T <: ToString {
    return "泛型: ${a}"
}

func process<T>(a: T, b: T): String where T <: ToString {
    return "泛型两个: ${a}, ${b}"
}

main() {
    println(process(10)) // 输出: 单个整数: 10
    println(process(10, 20)) // 输出: 两个整数: 10, 20
    println(process("Hello")) // 输出: 字符串: Hello
    println(process(3.14)) // 输出: 浮点数: 3.14
    println(process(true)) // 输出: 泛型: true
    println(process(1, 2)) // 输出: 泛型两个: 1, 2
}

7.2 构造函数重载

cangjie 复制代码
class Person {
    var email: String

    // 主构造函数
    Person(var name: String, var age: Int64) {
        this.name = name
        this.age = age
        this.email = ""
    }

    // 重载构造函数
    public init(name: String, age: Int64, email: String) {
        this.name = name
        this.age = age
        this.email = email
    }

    // 另一个重载构造函数
    public init(name: String) {
        this.name = name
        this.age = 0
        this.email = ""
    }
}

main() {
    let person1 = Person("张三", 25)
    let person2 = Person("李四", 30, "zh@example.com") 
    let person3 = Person("王五")
    
    println("${person1.name}, ${person1.age}")
    println("${person2.name}, ${person2.email}")
    println("${person3.name}, ${person3.age}")
}

7.3 重载决议规则

cangjie 复制代码
open class Animal {}
class Dog <: Animal {}
class Cat <: Animal {}

func feed(animal: Animal): String {
    return "喂食动物"
}

func feed(animal: Dog): String {
    return "喂食狗"
}

func feed(animal: Cat): String {
    return "喂食猫"
}

main() {
    let animal: Animal = Dog()
    let dog = Dog()
    let cat = Cat()
    
    // 重载决议选择最匹配的类型
    println(feed(animal)) // 输出: 喂食动物 (Animal类型),因为精准标注为了Animal,以Animal类型选择参数
    println(feed(dog))    // 输出: 喂食狗 (Dog类型)
    println(feed(cat))    // 输出: 喂食猫 (Cat类型)
}

8. 操作符重载

8.1 基本操作符重载

cangjie 复制代码
struct Point {
    var x: Int64
    var y: Int64

    public init(x: Int64, y: Int64) {
        this.x = x
        this.y = y
    }

    // 一元操作符重载
    public operator func -(): Point {
        Point(-x, -y)
    }

    // 二元操作符重载
    public operator func +(other: Point): Point {
        Point(x + other.x, y + other.y)
    }

    public operator func -(other: Point): Point {
        Point(x - other.x, y - other.y)
    }

    public operator func *(scalar: Int64): Point {
        Point(x * scalar, y * scalar)
    }

    // 比较操作符重载
    public operator func ==(other: Point): Bool {
        x == other.x && y == other.y
    }

    public operator func !=(other: Point): Bool {
        !(this == other)
    }
}

main() {
    let p1 = Point(3, 4)
    let p2 = Point(1, 2)

    let negP1 = -p1 // 使用一元操作符
    let sum = p1 + p2 // 使用二元操作符
    let diff = p1 - p2 // 使用二元操作符
    let scaled = p1 * 2 // 使用二元操作符

    println("P1: (${p1.x}, ${p1.y})")
    println("P2: (${p2.x}, ${p2.y})")
    println("Neg P1: (${negP1.x}, ${negP1.y})")
    println("Sum: (${sum.x}, ${sum.y})")
    println("Diff: (${diff.x}, ${diff.y})")
    println("Scaled: (${scaled.x}, ${scaled.y})")
    println("P1 == P2: ${p1 == p2}")
}

8.2 索引操作符重载

cangjie 复制代码
class Matrix {
    private var data: Array<Array<Int64>>
    private var rows: Int64
    private var cols: Int64

    public init(rows: Int64, cols: Int64) {
        this.rows = rows
        this.cols = cols
        this.data = Array(rows, {row => Array(cols, {col => 0})})
    }

    // 取值操作符重载
    public operator func [](row: Int64, col: Int64): Int64 {
        if (row >= 0 && row < rows && col >= 0 && col < cols) {
            return data[row][col]
        }
        return 0
    }

    // 赋值操作符重载
    public operator func [](row: Int64, col: Int64, value!: Int64): Unit {
        if (row >= 0 && row < rows && col >= 0 && col < cols) {
            data[row][col] = value
        }
    }

    public func printMatrix() {
        for (i in 0..rows) {
            for (j in 0..cols) {
                print("${data[i][j]} ")
            }
            println()
        }
    }
}

main() {
    let matrix = Matrix(3, 3)

    // 设置值
    matrix[0, 0] = 1
    matrix[0, 1] = 2
    matrix[0, 2] = 3
    matrix[1, 0] = 4
    matrix[1, 1] = 5
    matrix[1, 2] = 6
    matrix[2, 0] = 7
    matrix[2, 1] = 8
    matrix[2, 2] = 9

    println("矩阵内容:")
    matrix.printMatrix()

    // 读取值
    println("matrix[1,1] = ${matrix[1, 1]}")
    println("matrix[2,0] = ${matrix[2, 0]}")
}

8.3 函数调用操作符重载

cangjie 复制代码
class FunctionWrapper<T> {
    private var value: T
    
    public init(value: T) {
        this.value = value
    }
    
    // 函数调用操作符重载
    public operator func ()(newValue: T): T {
        let oldValue = value
        value = newValue
        return oldValue
    }
    
    // 无参数调用
    public operator func ()(): T {
        return value
    }
    
    public func getValue(): T {
        return value
    }
}

main() {
    let wrapper = FunctionWrapper<String>("初始值")
    
    println("初始值: ${wrapper()}")
    
    let oldValue = wrapper("新值")
    println("旧值: ${oldValue}")
    println("当前值: ${wrapper()}")
    
    // 直接调用
    println("直接调用: ${wrapper()}")
}

9. 函数调用语法糖

9.1 尾随 Lambda

cangjie 复制代码
import std.collection.ArrayList
func withTimeout(timeout: Int64, operation: () -> String): String {
    // 模拟超时操作
    if (timeout > 0) {
        return operation()
    }
    return "超时"
}

func processData(data: Array<Int64>, processor: (Int64) -> Int64): Array<Int64> {
    var result = ArrayList<Int64>()
    for (item in data) {
        result.add(processor(item))
    }
    return result.toArray()
}

main() {
    // 普通调用
    let result1 = withTimeout(1000, {=> "操作完成"})

    // 尾随 lambda 调用。没有参数时可以省略=>
    let result2 = withTimeout(1000) {
        "操作完成"
    }

    let data = [1, 2, 3, 4, 5]
    // 普通调用
    let processed1 = processData(data, {x => x * 2})

    // 尾随 lambda 调用
    let processed2 = processData(data) {
        x => x * 2
    }

    println("Result1: ${result1}")
    println("Result2: ${result2}")
    println("Processed1: ${processed1}")
    println("Processed2: ${processed2}")
}

9.2 Pipeline 表达式

cangjie 复制代码
import std.collection.ArrayList

func double(x: Int64): Int64 {
    x * 2
}

func addOne(x: Int64): Int64 {
    x + 1
}

func toString(x: Int64): String {
    "值: ${x}"
}

func processArray(arr: Array<Int64>): Array<Int64> {
    let result = ArrayList<Int64>()
    for (item in arr) {
        result.add(item)
    }
    return result.toArray()
}

func sumArray(arr: Array<Int64>): Int64 {
    var sum = 0
    for (item in arr) {
        sum += item
    }
    return sum
}

main() {
    let numbers = [1, 2, 3, 4, 5]

    // 使用 pipeline 操作符
    let result = numbers |> processArray |> sumArray |> double |> addOne |> toString

    println(result) // 输出: 值: 31

    // 等价于:
    let temp1 = processArray(numbers)
    let temp2 = sumArray(temp1)
    let temp3 = double(temp2)
    let temp4 = addOne(temp3)
    let result2 = toString(temp4)

    println(result2) // 输出: 值: 31
}

9.3 Composition 表达式

cangjie 复制代码
func f(x: Int64): Float64 {
    Float64(x)
}

func g(x: Float64): String {
    "结果: ${x}"
}

func h(x: String): String {
    x + "!"
}

main() {
    // 函数组合
    let fg = f ~> g
    let fgh = f ~> g ~> h

    println(fg(10)) // 输出: 结果: 10.0
    println(fgh(20)) // 输出: 结果: 20.0!

    // 等价于:
    let composed = {x: Int64 => h(g(f(x)))}
    println(composed(30)) // 输出: 结果: 30.0!
}

10. const 函数与常量求值

10.1 const 函数定义

cangjie 复制代码
const func factorial(n: Int64): Int64 {
    if (n <= 1) {
        1
    } else {
        n * factorial(n - 1)
    }
}

const func power(base: Int64, exp: Int64): Int64 {
    if (exp == 0) {
        1
    } else if (exp == 1) {
        base
    } else {
        base * power(base, exp - 1)
    }
}

const func gcd(a: Int64, b: Int64): Int64 {
    if (b == 0) {
        a
    } else {
        gcd(b, a % b)
    }
}

main() {
    // 这些计算在编译时完成
    const fact5 = factorial(5) // 120
    const pow2_8 = power(2, 8) // 256
    const gcdResult = gcd(48, 18) // 6

    println("5! = ${fact5}")
    println("2^8 = ${pow2_8}")
    println("GCD(48, 18) = ${gcdResult}")
}

10.2 const 构造函数

cangjie 复制代码
struct Point {
    const Point(let x: Float64, let y: Float64) {
    }

    const func distance(other: Point): Float64 {
        let dx = x - other.x
        let dy = y - other.y
        (dx * dx + dy * dy) ** 0.5
    }
}

class Circle {
    const Circle(let center: Point, let radius: Float64) {
    }

    const func area(): Float64 {
        3.1415926 * radius * radius
    }
}

main() {
    const p1 = Point(0.0, 0.0)
    const p2 = Point(3.0, 4.0)
    const circle = Circle(p1, 5.0)

    const dist = p1.distance(p2)
    const area = circle.area()

    println("距离: ${dist}")
    println("面积: ${area}")
}

11. 高级函数特性

11.1 函数柯里化

cangjie 复制代码
func curry<T, U, V>(f: (T, U) -> V): (T) -> (U) -> V {
    return {a: T => {b: U => f(a, b)}}
}

func add(a: Int64, b: Int64): Int64 {
    a + b
}

func multiply(a: Int64, b: Int64): Int64 {
    a * b
}

main() {
    let curriedAdd = curry(add)
    let curriedMultiply = curry(multiply)

    let add5 = curriedAdd(5)
    let multiply3 = curriedMultiply(3)

    println(add5(3)) // 输出: 8
    println(multiply3(4)) // 输出: 12
}

11.2 函数组合器

cangjie 复制代码
func compose<T, U, V>(f: (U) -> V, g: (T) -> U): (T) -> V {
    return {x: T => f(g(x))}
}

func pipe<T, U, V>(f: (T) -> U, g: (U) -> V): (T) -> V {
    return {x: T => g(f(x))}
}

func identity<T>(x: T): T {
    x
}

func constant<T, U>(x: T): (U) -> T {
    {_ => x}
}

main() {
    func double(x: Int64): Int64 {
        x * 2
    }
    func addOne(x: Int64): Int64 {
        x + 1
    }
    func toString(x: Int64): String {
        "结果: ${x}"
    }

    let doubleThenAddOne = compose(addOne, double)
    let addOneThenDouble = pipe(addOne, double)
    let fullPipeline = compose(toString, compose(addOne, double))

    println(doubleThenAddOne(5)) // 输出: 11
    println(addOneThenDouble(5)) // 输出: 12
    println(fullPipeline(5)) // 输出: 结果: 11
}

11.3 高阶函数实现

cangjie 复制代码
import std.collection.ArrayList

func map<T, U>(arr: Array<T>, f: (T) -> U): Array<U> {
    let result = ArrayList<U>()
    for (item in arr) {
        result.add(f(item))
    }
    return result.toArray()
}

func filter<T>(arr: Array<T>, predicate: (T) -> Bool): Array<T> {
    let result = ArrayList<T>()
    for (item in arr) {
        if (predicate(item)) {
            result.add(item)
        }
    }
    return result.toArray()
}

func reduce<T, U>(arr: Array<T>, initial: U, reducer: (U, T) -> U): U {
    var result = initial
    for (item in arr) {
        result = reducer(result, item)
    }
    return result
}

main() {
    let numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    // 映射:每个数翻倍
    let doubled = map(numbers, {x => x * 2})

    // 过滤:只保留偶数
    let evens = filter(numbers, {x => x % 2 == 0})

    // 归约:求和
    let sum = reduce(numbers, 0, {acc, x => acc + x})

    // 链式操作
    let result = numbers
        |> {arr => map(arr, {x => x * 2})}
        |> {arr => filter(arr, {x => x > 10})}
        |> {arr => reduce(arr, 0, {acc, x => acc + x})}

    println("原始数组: ${numbers}")
    println("翻倍后: ${doubled}")
    println("偶数: ${evens}")
    println("总和: ${sum}")
    println("链式操作结果: ${result}")
}

12. 实际应用示例

12.1 事件处理系统

cangjie 复制代码
type EventHandler = (event: Any) -> Unit

class EventBus {
    private var handlersMap: HashMap<String, ArrayList<EventHandler>> = HashMap()

    func subscribe(eventType: String, handler: EventHandler): Unit {
        if (!handlersMap.contains(eventType)) {
            handlersMap.add(eventType, ArrayList())
        }
        let eventTypeHandlers = handlersMap.get(eventType).getOrThrow()
        eventTypeHandlers.add(handler)
    }

    func publish<T>(eventType: String, event: T): Unit {
        if (let Some(eventTypeHandlers) <- handlersMap.get(eventType)) {
            for (handler in eventTypeHandlers) {
                handler(event)
            }
        }
    }
}

// 事件类型
class UserEvent {
    let userId: String
    let action: String

    init(userId: String, action: String) {
        this.userId = userId
        this.action = action
    }
}

class OrderEvent {
    let orderId: String
    let amount: Float64

    init(orderId: String, amount: Float64) {
        this.orderId = orderId
        this.amount = amount
    }
}

main() {
    let eventBus = EventBus()

    // 订阅用户事件
    eventBus.subscribe("user") {
        data: Any => if (let Some(event) <- (data as UserEvent)) {
            println("处理用户事件: ${event.userId} - ${event.action}")
        }
    }

    // 订阅订单事件
    eventBus.subscribe("order") {
        data: Any => if (let Some(event) <- (data as OrderEvent)) {
            println("处理订单事件: ${event.orderId} - ${event.amount}")
        }
    }

    // 发布事件
    eventBus.publish("user", UserEvent("user123", "login"))
    eventBus.publish("order", OrderEvent("order456", 99.99))
}

总结

仓颉编程语言的函数系统设计非常全面和强大,涵盖了现代编程语言中函数的所有重要特性:

核心特性

  1. 函数定义灵活:支持命名参数、默认值、类型推导
  2. 一等公民:函数可以作为参数、返回值和变量
  3. 闭包支持:完整的变量捕获机制
  4. 函数重载:基于参数类型和数量的重载系统
  5. 操作符重载:支持自定义操作符行为

高级特性

  1. Lambda 表达式:简洁的匿名函数语法
  2. 语法糖:尾随 lambda、pipeline、composition 等
  3. const 函数:编译时求值支持
  4. 嵌套函数:支持函数内部定义函数
  5. 变长参数:灵活的参数传递

设计优势

  1. 类型安全:强类型系统确保函数调用的正确性
  2. 性能优化:const 函数支持编译时计算
  3. 代码简洁:丰富的语法糖减少样板代码
  4. 扩展性强:操作符重载和扩展机制
  5. 函数式编程:支持高阶函数和函数组合

仓颉的函数系统不仅满足了基本的函数编程需求,还提供了许多现代编程语言的高级特性,使得开发者能够编写出更加优雅、高效和可维护的代码。无论是面向对象编程、函数式编程还是混合编程范式,仓颉都能提供强大的支持。

参考资料

相关推荐
HarderCoder10 分钟前
重学仓颉-7类与接口完全指南:从基础到高级特性
harmonyos
HarderCoder4 小时前
重学仓颉-6枚举与模式匹配完全指南
harmonyos
li理4 小时前
鸿蒙应用开发完全指南:深度解析UIAbility、页面与导航的生命周期
前端·harmonyos
HarderCoder6 小时前
重学仓颉-5结构体(Struct)完全指南:从基础到高级用法
harmonyos
HarmonyOS小助手6 小时前
【推荐+1】HarmonyOS官方模板优秀案例 (第4期:餐饮行业 · 美食菜谱)
harmonyos·鸿蒙·鸿蒙生态
HarderCoder12 小时前
重学仓颉-3基本数据类型详解:从理论到实践的全面指南
harmonyos
鸿蒙小灰13 小时前
鸿蒙OpenCV移植技术要点
opencv·harmonyos
鸿蒙先行者13 小时前
鸿蒙分布式能力调用失败解决方案及案例
分布式·harmonyos
大雷神1 天前
鸿蒙中应用闪屏解决方案
华为·harmonyos