类型扩展****
仓颉支持类型扩展特性,允许我们在不改变原有类型定义代码的情况下,为类型增加成员函数等功能。具体来说:
仓颉的类型扩展可以对已有的类型做如下几类扩展:
l 添加函数
l 添加属性
l 添加操作符重载
l 实现接口
下面的例子中,我们为String类型增加了printSize成员函数,因此在下面的代码中就可以像调用其他预定义的成员函数一样来调用printSize。
| extend String { func printSize() { print(this.size) }} "123".printSize() // 3 |
|---|
而当扩展和接口搭配使用的时候,它更能大幅提升语言的表达能力,我们甚至可以给已有的类型添加新的继承体系。
在下面的例子中,我们可以定义一个新接口Integer,然后用extend给已有的整数类型实现 Integer 接口,这样已有的整数类型就自然成为了 Integer 的子类型。其中sealed修饰符表示该接口只能在当前包中被实现(或扩展)。
| sealed interface Integer {}extend Int8 <: Integer {}extend Int16 <: Integer {}extend Int32 <: Integer {}extend Int64 <: Integer {}let a: Integer = 123 // ok |
|---|
类型推断****
类型推断是指由编译器根据程序上下文自动推断变量或表达式的类型,而无需开发者显式写出。
仓颉作为现代编程语言,对类型推断也提供了良好的支持。
在仓颉中变量的定义可以根据初始化表达式的类型来推断其类型。除了变量以外,仓颉还额外支持了函数定义返回值类型的推断。在仓颉中,函数体的最后一个表达式会被视为这个函数的返回值。像变量一样,当函数定义省略了返回类型,函数就会通过返回值来推断返回类型。
| var foo = 123 // foo 是 'Int64'var bar = 'hello' // bar 是 'String' func add(a: Int, b: Int) { // add 返回 Int a + b} |
|---|
仓颉还支持在泛型函数调用中推断类型参数,包括对柯里化函数里泛型参数的推断,如下面的例子所示:
| func map<T, R>(f: (T)->R): (Array)->Array { ...} map({ i => i.toString() })([1, 2, 3]) // 支持推断泛型柯里化函数// 推断结果为map<Int, String>({ i => i.toString() })([1, 2, 3]) |
|---|
注意 lambda 表达式作为map的第一个参数,它的参数类型(T)和返回值类型(R)都可以被推断出来,尽管参数类型(T)的推断还反过来依赖对map的第二个参数的类型(Array)的推断。