在仓颉语言中,泛型(Generics)和类型扩展(Extension)是两大极具生产力的特性。如果说多范式支持是仓颉的灵魂,那么泛型和扩展机制就是仓颉提升开发效率、提升代码复用性的利器。在我实际开发HarmonyOS Next应用的过程中,泛型和扩展不仅帮助我极大地减少了重复代码,还让系统架构更加清晰、灵活。本篇,我们就通过实战视角,深入探索这两个强力特性。

泛型编程:一次编写,多处使用

泛型(Generics)允许我们在定义类、接口、函数时使用类型参数,而不是绑定到具体某个类型。这种抽象不仅提高了代码复用率,而且还能在编译期提供类型安全保障。

仓颉语言中的泛型应用场景

场景示例
泛型类Array<T>、Map<K, V>
泛型函数func concat<T>(lhs: Array<T>, rhs: Array<T>)
泛型接口interface Repository<T>
泛型扩展extend泛型类型

示例:实现数组拼接的泛型函数

假设我们希望实现一个可以拼接任意类型数组的函数,传统做法需要针对不同类型各写一遍,但用仓颉的泛型只需一次定义:

func concat<T>(lhs: Array<T>, rhs: Array<T>): Array<T> {
    let defaultValue = if (lhs.size > 0) {
        lhs[0]
    } else if (rhs.size > 0) {
        rhs[0]
    } else {
        return []
    }

    let newArr = Array<T>(lhs.size + rhs.size, item: defaultValue)
    newArr[0..lhs.size] = lhs
    newArr[lhs.size..lhs.size+rhs.size] = rhs
    return newArr
}

main() {
    let a = [1, 2, 3]
    let b = [4, 5, 6]
    println(concat(a, b)) // 输出 [1,2,3,4,5,6]
}
  1. T是泛型类型参数,可以是IntString、甚至是自定义对象。
  2. 类型推断让调用时几乎无需关心泛型细节,体验非常丝滑。

泛型约束:精准控制可用类型

在一些泛型场景下,我们不仅关心类型参数是啥,还希望限定它必须支持某些操作,比如判等、排序等。仓颉通过where子句支持泛型约束,示例:

func lookup<T>(element: T, arr: Array<T>): Bool where T <: Equatable {
    for (let e in arr) {
        if (element == e) {
            return true
        }
    }
    return false
}

这里,T <: Equatable表示,T必须是支持相等比较的类型,否则编译器会拒绝实例化。

技术点说明
<:子类型约束(必须实现某接口)
Equatable表示支持等值比较

实践感受:这种设计兼顾了灵活性与安全性,大大避免了运行时类型错误。

类型扩展:无侵入地增强已有类型

仓颉语言另一个让我非常喜欢的特性是类型扩展(Extension)。它允许我们在不修改原有定义的前提下,给已有类型增加新功能,极大提升了代码组织性和可维护性。

示例:给String类型扩展新方法

比如,我们想要给所有String对象增加一个打印长度的方法:

extend String {
    func printSize() {
        println(this.size)
    }
}

main() {
    "HarmonyOS".printSize() // 输出 9
}
  1. extend 类型名开启扩展
  2. this表示当前对象
  3. 扩展方法使用体验与内置方法无异

更进一步:扩展并添加接口实现

仓颉甚至允许在扩展中让已有类型实现新的接口!

sealed interface Integer {}

extend Int8 <: Integer {}
extend Int16 <: Integer {}
extend Int32 <: Integer {}
extend Int64 <: Integer {}

main() {
    let a: Integer = 123
    println(a)
}
  1. sealed表示接口只允许在当前包中被实现。
  2. 通过扩展,原本与Integer接口无关的基本类型现在也能享受接口编程的便利了。

总结一张表:仓颉泛型与扩展特性一览

特性描述实战场景示例
泛型类/接口使用类型参数构建通用结构Array<T>, Repository<T>
泛型函数处理不同类型数据的通用算法concat<T>, lookup<T>
泛型约束限制泛型类型必须满足某接口where T <: Equatable
类型扩展(方法)给已有类型添加新方法String.printSize()
类型扩展(接口)让已有类型实现新接口Int32 <: Integer

小结

在HarmonyOS Next开发过程中,仓颉语言的泛型与扩展机制可以极大提升我们开发复杂系统时的复用性、灵活性与可维护性。我的真实体会是:

  1. 泛型让工具类、数据结构设计变得异常优雅,减少了大量模板代码。
  2. 扩展让我们可以以一种“开放 - 封闭”的方式增强已有代码,而不破坏原有体系结构。

如果你追求写出既优雅又健壮的代码,那么掌握泛型与扩展,无疑是必修课。


SameX
1 声望2 粉丝