一、限制运算符的语义
为获得更好的性能并鼓励开发者编写更清晰的代码,ArkTS限制了一些运算符的语义。详细的语义限制。
示例
// 一元运算符`+`只能作用于数值类型:
let t = +42; // 合法运算
let s = +'42'; // 编译时错误
使用额外的语义重载语言运算符会增加语言规范的复杂度,而且,开发者还被迫牢记所有可能的例外情况及对应的处理规则。在某些情况下,产生一些不必要的运行时开销。
当前只有不到1%的代码库使用该特性。因此,尽管限制运算符的语义需要重构代码,但重构量很小且非常容易操作,并且,通过重构能使代码更清晰、具备更高性能。
二、不支持 structural typing
假设两个不相关的类T和U拥有相同的publicAPI:
class T {
public name: string = ''
public greet(): void {
console.log('Hello, ' + this.name);
}
}
class U {
public name: string = ''
public greet(): void {
console.log('Greetings, ' + this.name);
}
}
能把类型为T的值赋给类型为U的变量吗?
let u: U = new T(); // 是否允许?
能把类型为T的值传递给接受类型为U的参数的函数吗?
function greeter(u: U) {
console.log('To ' + u.name);
u.greet();
}
let t: T = new T();
greeter(t); // 是否允许?
换句话说,我们将采取下面哪种方法呢:
T和U没有继承关系或没有implements相同的接口,但由于它们具有相同的publicAPI,它们“在某种程度上是相等的”,所以上述两个问题的答案都是“是”;
T和U没有继承关系或没有implements相同的接口,应当始终被视为完全不同的类型,因此上述两个问题的答案都是“否”。
采用第一种方法的语言支持structural typing,而采用第二种方法的语言则不支持structural typing。目前TypeScript支持structural typing,而ArkTS不支持。
structural typing是否有助于生成清晰、易理解的代码,关于这一点并没有定论。那为什么ArkTS不支持structural typing呢?
因为对structural typing的支持是一个重大的特性,需要在语言规范、编译器和运行时进行大量的考虑和仔细的实现。另外,由于ArkTS使用静态类型,运行时为了支持这个特性需要额外的性能开销。
鉴于此,当前我们还不支持该特性。根据实际场景的需求和反馈,我们后续会重新加以考虑。
本文根据HarmonyOS NEXT Developer Beta1官方公开的开发文档整理而成。