首页 > 其他分享 >鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码

时间:2024-02-04 12:32:56浏览次数:31  
标签:ArkTS TypeScript name 鸿蒙 代码 重塑 HarmonyPractice

hi 大家好,我是 DHL。就职于美团、快手、小米。公众号:ByteCode,分享有用的原创文章,涉及鸿蒙、Android、Java、Kotlin、性能优化、大厂面经

我最近建了一个鸿蒙开发者交流群,群里有大佬说在 gitee 鸿蒙仓库中可以下载 DevEco Studio 4.0。于是我下载体验了一下,运行了官方提供示例项目 Shopping 出现了 422 个 Error 级别的错误,导致项目根本无法编译,于是我把这 422 个 Error 级别的错误 从头到尾改了一遍,可以理解为,我把核心代码重写了一遍,后面我会分享在 github 上。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_前端

出现这些错误的原因是因为 DevEco Studio 4.0 有一个非常重要的更新,进行代码编译时会对不符合 ArkTS 语法规则的代码进行告警。

告警分为两个级别:错误、警告。

  • 错误(Error): 必须要遵的规范。如果不遵从规范,将会导致程序编译失败
  • 警告(Warning): 推荐遵从的规范,尽管现在违反该规范不会影响编译流程,但是在将来,违反该规范可能将会导致程序编译失败,所以尽量遵守规范

这个更新既是开发者福音,有是开发者的噩梦,好处在于从编译器层面对开发规范进行了强制约束,有助于提高代码的可靠性和可维护性。可以帮助开发者编写更加健壮和可靠的代码。但是不好的一点,因为 TypeScript 的语言非常的自由,如果你没有按照社区的规范去写,那么升级到 DevEco Studio 4.0 你将面临大量的语法适配工作。

鸿蒙官方提供的示例 Shopping 就是一个经典的反面教材,导入 DevEco Studio 4.0 中运行出现了 422 个 Error 级别的错误

ArkTS 是在 TypeScript 的基础上扩展的,而 TypeScript 是在 JavaScript 的基础上扩展的,为了兼容 JavaScript,TypeScript 在很多方面都做了妥协。如果是移动端开发者,首次接触 TypeScript 和 JavaScript 的项目的时候,会觉得项目代码乱七八糟的,

核心原因 JavaScript 是非常的灵活的语言,开发者可以按照自己的想法去写,比如没有类型约束,一个变量可能初始化时是字符串,过一会儿又被赋值为数字,而 TypeScript 虽然提供了静态类型约束,但是不是强制的,从而导致了开发者可以按照自己的想法随意去写,只要项目可以运行起来就没有人会去改。

而鸿蒙在编译器层面上进一步加强了 ArkTS 语法规则的检查,有助于提高代码的可靠性和可维护性。帮助开发者编写更加健壮和可靠的代码。

ArkTS 限制了 TypeScript 很多逆天语法,这篇主要介绍我在运行官方示例项目 Shopping 遇到的错误,熟悉这些后,再运行官方示例项目,不用在去网上找答案了,当然你在网上也很难找到这些错误的解决方案。

本文所有代码都已经上传到了 github HarmonyPractice 仓库,欢迎点击 HarmonyPractice 仓库右上角 star,同时我也打开了 Discussions 功能,欢迎来 Discussions 一起讨论。

HarmonyPractice:https://github.com/hi-dhl/HarmonyPractice

不支持 any 或 unknown 类型,禁止使用 var

在 ArkTS 中要求强制使用静态类型,我在之前的文章 鸿蒙:5 分钟秒懂 ArkTs,不能错过的知识点解析 介绍过,没有看过的小伙伴可以去看一下。

如果能够推断出具体的类型,ArkTS 允许省略具体类型,否则需要指定具体类型,不然会报错。并且不能使用 any 和 unknown 类型。

为什么不能使用 any 和 unknown 类型,我举一个例子,以下代码在 TypeScript 中是可以运行的。
HarmonyPractice/Basic/entry/src/main/ets/syntax/TestType1. ts

示例1
let type: any
type = true;
type = 42;

示例2
getValue(type: any){ 

}
this.getValue(1)
this.getValue(true)

当你在看到这些代码的时候,不知心里作何感想,一个变量声明为 any 类型,初始可能是 boolean 类型,过一会儿又被赋值为数字,然而这些代码在 TypeScript 中是可以运行的。这种写法是非常的不安全,存在很大的安全隐患。

上面的示例,在 ArkTS 中是被允许的,编译器就会给你一个大大的错误提示。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_Android_02

所以在 ArkTS 中我们应该这么写:
HarmonyPractice/Basic/entry/src/main/ets/syntax/TestType2. ets

const type: number = 1;   // or  const type = 1
let bool: boolean = true; // or  let bool = true

// 如果你不确定类型,可以使用 object
let ob: object = []

constlet 的原理和区别,以及在什么场景下使用,我在之前的文章 鸿蒙:5 分钟秒懂 ArkTs,不能错过的知识点解析 做了详细的介绍。

需要注意的是在 TypeScript 中可以使用 var,但是不推荐,在 ArkTS 中禁止使用 var。因为是用 var 会带来很多问题。

if (true) {
    var message = "DHL";
}
console.log(message); // 输出 "DHL",而不是报错

我们希望运行上面的代码报错,但是在 TypeScript 中不仅不会报错,而且还会输出 "DHL",这是因为 var 声明的变量,在全局范围内都有效,因此在 if 语句外面也能获取到。

不支持解构赋值

解构赋值在 TypeScript 项目中非常的常见。解构赋值虽然方便,但是降低了代码的可读性和可维护性,先来看一个示例。示例中的代码在 TypeScript 中可以运行的。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Destruct1. ts

let [head, ...tail] = [1, 2, 3, 4];

我们先来解释一下这段代码,示例中使用解构赋值从数组 [1, 2, 3, 4] 中提取值。解构赋值的语法 [head, ...tail] 表示我们想要从数组中提取第一个元素赋给 head,并将剩余的元素以数组的形式赋给 tail

因此,经过这行代码后,head 的值将是 1,而 tail 的值将是数组 [2, 3, 4]。解构赋值很方便,越方便越容易被开发者滥用,解构赋值可能会导致代码变得难以理解,尤其是复杂的嵌套结构,降低了代码的可读性和可维护性,因此在 ArkTS 禁止这样写,上面示例在 ArkTS 中会报错。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_开发者_03

因此在 ArkTS 中我们应该这样写。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Destruct2. ets

const data: Number[] = [1, 2, 3, 4];
const len = data.length;
let head = data[0];
let tail: Number[] = [];
for (let i = 1; i < len; ++i) {
  tail.push(data[i]);
}

更多示例,可以前往 github HarmonyPractice 仓库查看。

不支持参数解构的函数声明

函数的参数解构,在 TypeScript 项目中,也是非常的常见的写法,使用起来非常的方便。
HarmonyPractice/Basic/entry/src/main/ets/syntax/DestructParams1. ts

request({ location: [lat, lon], name: string}) {
// 在这个方法中,我们接收一个包含 location 和 name 属性的对象作为参数
// location 是一个数组,包含两个元素,分别是经度和纬度
// name 是一个字符串
}

testRequest() {
    // 在这个方法中,我们调用了上面定义的 request 方法,并传入一个对象作为参数
    this.request({ location: [10, 10], name: "DHL" })
}

我们先解释一下这段代码,在 testRequest 方法中,我们调用了 request 方法,并传入了一个包含 locationname 属性的对象作为参数。其中 location 是一个数组,包含经度和纬度,而 name 是一个字符串。

参数的解构虽然方便,但是导致的结果代码变得难以理解,因此在 ArkTS 禁止这样写,上面示例在 ArkTS 中会报错。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_开发者_04

因此在 ArkTS 中我们应该这样写。
HarmonyPractice/Basic/entry/src/main/ets/syntax/DestructParams2. ets

request(location: number[], name: string) {
    // location 是一个数组,包含两个元素,分别是经度和纬度
    // name 是一个字符串
}

testRequest() {
    // 在这个方法中,我们调用了上面定义的 request 函数,并传入一个对象作为参数
    this.request([10, 10], "DHL")
}

不支持在 catch 语句标注类型

在 ArkTS 中要求强制使用静态类型,如果能够推断出具体的类型,ArkTS 允许省略具体类型,否则需要指定具体类型。但是 catch 语句中有点不一样,先看示例代码。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Exception1. ts

try {
  // ...
} catch (error: unknown) {
  // 处理异常
}

上面的代码在 TypeScript 中是可以正常运行的,这是因为 TypeScript 支持 any 或 unknown 类型,而 catch 语句中 error 只能声明为 any 或 unknown 类型,但是在 ArkTS 中运行,编译会给你一个大大的错误提示。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_JavaScript_05

因为在 ArkTS 中不支持 any 或 unknown,所以这里应应省略类型标注。因此在 ArkTS 中代码如下所示。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Exception2. ets

try {
  // ...
} catch (error) {
  // 处理异常
}

类型的别名与变量不能同名

在 TypeScript 中下面的代码是合法的。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Type1. ts

let value: string
type value = number[] // 类型的别名与变量同名

但是在 ArkTS 中不允许这么写。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Type2. ets

let value: string
type ages = number[] // 为避免名称冲突,此处不允许使用 value

类中仅支持一个静态块

在 TypeScript 中可以在类中使用多个静态代码块。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Static1. ts

class Person{
  static {
    let name = "dhl"
  }
  static {
    let age = 10;
  }
}

虽然 TypeScript 支持,但是我还没见过有人会在类中定义多个静态代码块。在 ArkTS 中不允许类中有多个静态块,和 Kotlin 或者 Java 语言对齐的,如果使用多个,编译器会给出错误提示,因此我们需要将多个合并为 1 个。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_前端_06

不支持在 constructor 中声明类字段

在 TypeScript 中可以直接在类的 constructor 中声明类字段,代码如下所示。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Constructor1. ts

class Person {
  constructor(
    private name: string
  ) {
    this.name = name;
  }

  getFullName(): string {
    return this.name;
  }
}

正如你所见,在 constructor 中声明字段 name,然后在 getFullName() 方法中可以使用 name,但是在 ArkTS 中不支持在 constructor 中声明类字段,编译器直接会报错。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_开发者_07

在 ArkTS 中应该这么写,这和 Kotlin 或者 Java 在类中的使用是一样。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Constructor2. ets

class Person {
  private name: string

  constructor(name: string) {
    this.name = name;
  }

  getFullName(): string {
    return this.name;
  }
}

数组必须仅包含可推断类型的元素

在 ArkTS 中,数组中的元素必须是可以根据上下文推断出来的类型,如果类型无法推断出来,则会报错,代码如下所示。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Array1. ts

export const persons: Array<Person> = [
  { "name": "DHL" },
  { "name": "ByteCode" },
]

上面的代码在 TypeScript 中可以正常运行,当看到这段代码有没有觉得很奇怪,创建一个对象,这个对象的元素和类 Person 成员变量一致,就可以往数组中添加,我还是第一次见到代码可以这样写。切换到 ArkTS 会报错,禁止这样写。

鸿蒙:揭晓 ArkTS,重塑语法,打造更健壮和可靠的代码_JavaScript_08

在 ArkTS 中正确示例如下所示。
HarmonyPractice/Basic/entry/src/main/ets/syntax/Array2. ets

export const persons: Array<Person> = [
  new Person("DHL"),
  new Person("ByteCode"),
]

因为篇幅问题,这里我只介绍了运行官方示例项目中遇到的错误,后面我还会分享更多 ArkTs 语法约束。本文所有代码已上传到 github。

感谢你的阅读,写技术文章不易,如果文章对你有帮助,欢迎在看、点赞、分享给身边的朋友,你的点赞是我持续更新的动力

我在 github 上新建了一个 HarmonyPractice 仓库,这个仓库主要用于演示 ArkTS 语法规则、鸿蒙组件的使用,以及鸿蒙实战项目。

本文所有代码已上传到 HarmonyPractice 仓库 Basic 工程中,这个工程主要用于演示 ArkTS 的语法,会第一时间同步鸿蒙新增的语法约束,本文所有的代码均在 Basic 工程中,欢迎点击 HarmonyPractice 仓库右上角 star 以兹鼓励。

HarmonyPractice:https://github.com/hi-dhl/HarmonyPractice

标签:ArkTS,TypeScript,name,鸿蒙,代码,重塑,HarmonyPractice
From: https://blog.51cto.com/u_13238266/9582569

相关文章

  • 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TimePicker组件
    鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TimePicker组件一、操作环境操作系统: Windows10专业版、IDE:DevEcoStudio3.1、SDK:HarmonyOS3.1+编辑二、TimePicker组件TextClock组件通过文本将当前系统时间显示在设备上。支持不同时区的时间显示,最高精度到秒级。子组件无。接口TimePic......
  • 鸿蒙开发有必要学吗?看完这篇再决定吧
    在科技的潮流中,每一次新操作系统的诞生都是对旧秩序的挑战与新机遇的孕育。鸿蒙操作系统的出现,无疑是近年来科技界最引人注目的事件之一。自华为于2019年正式推出鸿蒙系统以来,这一我们自主研发的操作系统不仅在国内引起巨大反响,更在全球范围内展示了中国科技的崛起。鸿蒙系统最初......
  • 盘点那些硬件+项目学习套件:Hi3861鸿蒙开发板及入门常见问题解答
    华清远见20岁了~过去3年里,华清远见研发中心针对个人开发板业务,打造了多款硬件+项目学习套件,涉及STM32单片机、嵌入式、物联网、人工智能、鸿蒙、ESP32、阿里云IoT等多技术方向。今天我们来盘点一下,比较受欢迎几款“硬件+项目”学习套件,以及一些初学者比较关注的问题。盘点二:Hi3861......
  • 外卖跑腿app开发:重塑都市生活的便捷与效率
    随着现代生活节奏的加快,人们对外出就餐和日常用品的需求日益增长,外卖和跑腿服务应运而生,逐渐成为日常生活中不可或缺的一部分。而这种需求的满足在很大程度上得益于外卖跑腿app的开发与应用。本文将对外卖跑腿app的发展历程、市场需求、功能特点、以及未来趋势进行深入探讨。一、外......
  • 【鸿蒙千帆起】高德地图携手HarmonyOS NEXT,开启智能出行新篇章
    2024年1月18日下午,华为举办了鸿蒙生态千帆启航仪式,对外宣布HarmonyOSNEXT星河预览版现已开放申请,同时,首批200+鸿蒙原生应用加速开发,鸿蒙生态设备数量更是突破了8亿大关。这些进展反映了开发者和合作伙伴对鸿蒙生态未来发展的坚定信心和美好期待。1月19日HarmonyOS应用开发技术分......
  • 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextClock组件
    鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextClock组件一、操作环境操作系统: Windows10专业版、IDE:DevEcoStudio3.1、SDK:HarmonyOS3.1+编辑二、TextClock组件TextClock组件通过文本将当前系统时间显示在设备上。支持不同时区的时间显示,最高精度到秒级。子组件无。接口TextClock......
  • 鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextPicker组件
    鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之TextPicker组件一、操作环境操作系统: Windows10专业版、IDE:DevEcoStudio3.1、SDK:HarmonyOS3.1+编辑二、TextPicker组件TextClock组件通过文本将当前系统时间显示在设备上。支持不同时区的时间显示,最高精度到秒级。子组件无。接口TextPic......
  • 鸿蒙开发丨设备内 UIAbility 的几种交互方式
    UIAbility组件间交互(设备内)在设备内,UIAbility(用户界面能力)是系统调度的最小单元,它们负责展示用户界面和执行相关的业务逻辑。设备内的不同功能模块之间的交互是应用程序开发中的重要部分。本文将探讨设备内UIAbility之间的交互方式,包括启动应用内的UIAbility、启动其他应用的U......
  • 鸿蒙开发游戏(一)---大鱼吃小鱼(界面部署)
    鸿蒙开发游戏(一)---大鱼吃小鱼(界面部署)鸿蒙开发游戏(二)---大鱼吃小鱼(摇杆控制)鸿蒙开发游戏(三)---大鱼吃小鱼(放置NPC)鸿蒙开发游戏(四)---大鱼吃小鱼(互吃升级)鸿蒙开发游戏(五)---大鱼吃小鱼(添加音效)鸿蒙开发游戏(六)---大鱼吃小鱼(称霸海洋) 前言:你是否玩过古老而不失优雅的大鱼吃小鱼......
  • 纯血鸿蒙来了,鸿蒙App开发有可能提速吗?
    “全世界做产品挣钱的公司很多,但有能力打造操作系统的公司没有几家,最后世界上的操作系统就只有三套:鸿蒙、iOS和安卓。”---360集团创始人、董事长周鸿祎 “HarmonyOS实现了AI框架、大模型、设计系统、编程框架、编程语言、编译器等全栈自研,有核心技术、全栈能力、底座和生......