首页 > 编程笔记 > 通用技能 阅读:3

ArkTS中的泛型(附带实例)

ArkTS 中的泛型类型允许创建的代码在各种类型上运行,而不仅支持单一类型。

泛型类和泛型接口

类和接口可以定义为泛型,将参数添加到类型定义中,如以下示例中的类型参数 Element:
class CustomStack<Element> {
  public push(e: Element): void {
    // ...
  }
}
要使用类型 CustomStack,必须为每个类型参数指定类型实参:
let s = new CustomStack<string>();
s.push('hello');
编译器在使用泛型类型和函数时会确保类型安全。示例如下:
let s = new CustomStack<string>();
s.push(55); // 将会产生编译时错误

泛型约束

泛型类型的类型参数可以被限制只能获取某些特定的值。例如,MyHashMap<Key, Value>这个类中的 Key 类型参数必须具有 hash 方法。
interface Hashable {
  hash(): number;
}

class MyHashMap<Key extends Hashable, Value> {
  public set(k: Key, v: Value) {
    let h = k.hash();
    // ...其他代码...
  }
}
在上面的例子中,Key 类型扩展了 Hashable,Hashable 接口的所有方法都可以被 key 调用。

泛型函数

使用泛型函数可编写更通用的代码。比如返回数组最后一个元素的函数:
function last(x: number[]): number {
  return x[x.length - 1];
}
last([1, 2, 3]); // 3

如果需要为任何数组定义相同的函数,使用类型参数将该函数定义为泛型:
function last<T>(x: T[]): T {
  return x[x.length - 1];
}
现在,该函数可以与任何数组一起使用。

在函数调用中,类型实参可以显式或隐式设置:
// 显式设置的类型实参
last<string>(['aa', 'bb']);
last<number>([1, 2, 3]);

// 隐式设置的类型实参
// 编译器根据调用参数的类型来确定类型实参
last([1, 2, 3]);

泛型默认值

泛型类型的类型参数可以设置默认值。这样可以不指定实际的类型实参,而只使用泛型类型名称。下面的示例展示了类和函数的这一点。
class SomeType {}

interface Interface<T1 = SomeType> {}

class Base<T2 = SomeType> {}

class Derived1 extends Base implements Interface {}
// Derived1 在语义上等价于 Derived2
class Derived2 extends Base<SomeType> implements Interface<SomeType> {}

function foo<T = number>(): T {
  // ...
}

foo();
// 此函数在语义上等价于下面的调用
foo<number>();

相关文章