HarmonyOS学习记录3
本文为个人学习记录,仅供参考,如有错误请指出。本文主要记录ArkTS基础语法,仅记录了部分我觉得与其他语言不太类似的地方,具体规范请参考官方文档。
参考官方文档:https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101717496870909384
什么是ArkTS
ArkTS是一种设计用于构建高性能应用的编程语言。它在继承TypeScript语法的基础上进行了优化,以提供更高的性能和开发效率。许多编程语言在设计之初没有考虑到移动设备,导致应用的运行缓慢、低效、功耗大,随着移动设备在人们的日常生活中变得越来越普遍,针对移动环境的编程语言优化需求也越来越多。ArkTS是专为解决这些问题而设计的,聚焦于提高运行效率。TypeScript是在JavaScript基础上通过添加类型定义扩展而来的,ArkTS则是TypeScript的进一步扩展。TypeScript提供了一种更结构化的JavaScript编码方法,深受开发者喜爱。ArkTS保持了TypeScript的大部分语法,旨在为现有的TypeScript开发者实现无缝过渡,帮助移动开发者快速上手。ArkTS的一大特性是它专注于低运行时开销。ArkTS对TypeScript的动态类型特性施加了更严格的限制,以减少运行时开销,提高执行效率。通过取消动态类型特性,ArkTS代码能更有效地被运行前编译和优化,从而实现更快的应用启动和更低的功耗。ArkTS语言设计中考虑了与TypeScript和JavaScript的互通性。许多移动应用开发者希望重用TypeScript和JavaScript代码及库,因此ArkTS提供与TypeScript和JavaScript的无缝互通,使开发者可以轻松集成TypeScript和JavaScript代码到应用中,充分利用现有代码和库进行ArkTS开发。
声明
ArkTS通过声明引入变量、常量、类型和函数
变量声明
使用关键字let声明的变量可以在程序执行期间具有不同的值
let a : string = 'hello';
a = 'hello,world';
产量声明
使用关键字const声明的只读常量只能被赋值一次。注意,对常量重新赋值会造成编译时报错
const a : string = 'hello';
自动类型判断
由于ArkTS是一种静态类型语言,所有数据的类型都必须在编译时确定,如果常量或者变量在声明时就包含了初始值,则不需要显式指定其类型,ArkTS会自动根据场景自动推断类型,如下两种声明方式都是有效的,并且两个变量都是string类型
let a1 : string = 'hello';
let a2 = 'hello,a';
数据类型
number类型:在ArkTS中任何整数和浮点数都可以被赋值给此类型的变量,其范围包括:
- 整数字面量包括以下类别:
- 十进制整数,由数字序列组成。例如:0、117、-345
- 十六进制整数,以0x(或0X)开头,包含数字(0-9)和字母a-f或A-F。例如:0x1123、0x00111、-0xF1A7
- 八进制整数,以0o(或0O)开头,只能包含数字(0-7)。例如:0o777
- 二进制整数,以0b(或0B)开头,只能包含数字0和1。例如:0b11、0b0011、-0b11
- 可表示的最大整数范围:-9007199254740991~9007199254740991,超出范围时可用bigint类型来确保精度
- ⠀浮点数字面量包括以下部分:
- 十进制整数,可为有符号数(前缀为“+”或“-”)
- 小数点(“.”)
- 小数部分(由十进制数字字符串表示)
- 指数部分,以“e”或“E”开头,后跟有符号(前缀为“+”或“-”)或无符号整数
- 整数字面量包括以下类别:
boolean类型:true和false
string类型:字符串字面量由单引号(')或双引号(")之间括起来的零个或多个字符组成。字符串字面量还有一特殊形式,是用反向单引号(`)括起来的模板字面量
void类型
Object类型:此类型是所有引用类型的基类型。任何值,包括基本类型的值,都可以直接被赋给Object类型的变量(基本类型值会被自动装箱)
array类型:array类型,即数组,是由可赋值给数组声明中指定的元素类型的数据组成的对象。数组可由数组复合字面量赋值。数组复合字面量是用方括号括起来的零个或多个表达式列表,每个表达式为数组中的一个元素。数组的长度由数组中元素的个数确定。注意,数组中第一个元素的索引为0
enum类型:枚举类型
Union类型:即联合类型,是由多个类型组合成的引用类型
Aliases类型:为匿名类型(数组、函数、对象自面量或联合类型)提供名称,或为已有类型提供替代名称
可见性修饰符
- Public(公有)
- Private(私有)
- Protect(受保护):protected修饰符的作用与private修饰符非常相似,不同点是protected修饰的成员允许在派生类中访问,例如:
class Base {
protected x: string = '';
private y: string = '';
}
class Derived extends Base {
foo() {
this.x = 'a'; // OK,访问受保护成员
this.y = 'b'; // 编译时错误,'y'不可见,因为它是私有的
}
}
空安全
默认情况下,ArkTS中的所有类型都不允许为空,这类似于TypeScript的(strictNullChecks)模式,但规则更严格。在下面的示例中,所有行都会导致编译时错误:
let x: number = null; // 编译时错误
let y: string = null; // 编译时错误
let z: number[] = null; // 编译时错误
可以为空值的变量定义为联合类型T | null:
let x: number | null = null;
x = 1; // ok
x = null; // ok
if (x != null) { /* do something */ }
尝试完成一个Demo
本文只记录一些核心部分的代码以及遇到的问题,源码请查看官方链接
项目结构
├──entry/src/main/ets/
│ ├──common
│ │ ├──constants
│ │ │ └──Constants.ets // 常量类
│ │ └──utils
│ │ ├──CommonUtils.ets // 弹窗工具类
│ │ ├──Logger.ets // 日志工具类
│ │ └──Method.ets // 算法工具类
│ ├──entryability
│ │ └──EntryAbility.ets
│ ├──entrybackupability
│ │ └──EntryBackupAbility.ets
│ ├──pages
│ │ └──Index.ets // 界面实现
│ └──view
│ ├──DaffodilsNumberCustomDialog.ets // 水仙花数弹窗实现
│ ├──IsLeapYearCustomDialog.ets // 闰年判断数弹窗实现
│ ├──IsPalindromicStringCustomDialog.ets // 回文字符串判断数弹窗实现
│ ├──MultiplicationTableCustomDialog.ets // 九九乘法表弹窗实现
│ └──StringReversalCustomDialog.ets // 字符串反转弹窗实现
└───entry/src/main/resources // 应用资源目录
项目效果
核心代码
整体布局还是比较好写的,主要是这些按钮具体的实现方法比较麻烦,所以直接复制了官方的方法,在布局中绑定到对应的组件即可
// Method.ets
// 水仙花数
export function daffodilsNumber(): number[] {
let result: number[] = [];
for (let i = 100; i < 1000; i++) {
let unitsDigit: number = i % 10;
let tenthsDigit: number = Math.floor(i / 10) - Math.floor(i / 100) * 10;
let hundredthsDigit: number = Math.floor(i / 100);
if (i === unitsDigit * unitsDigit * unitsDigit + tenthsDigit * tenthsDigit * tenthsDigit +
hundredthsDigit * hundredthsDigit * hundredthsDigit) {
result.push(i);
}
}
return result;
}
// 九九乘法表
export function multiplicationTable(): string[][] {
let result: string[][] = [];
for (let i = 1; i <= 9; i++) {
let index: string[] = [];
for (let j = 1; j <= i; j++) {
let temp: string = j + ' * ' + i + ' = ' + i * j;
index.push(temp);
}
result.push(index);
}
return result;
}
// 回文判断
export function isPalindromicString(content: string): boolean {
let result: boolean = true;
let i: number = 0;
let j: number = content.length - 1;
while (i <= j) {
if (content.charAt(i) !== content.charAt(j)) {
result = false;
break;
}
i++;
j--;
}
return result;
}
// 字符串反译
export function StringReversal(content: string): string {
let result: string = '';
for (let index = content.length - 1; index >= 0; index--) {
result += content.charAt(index);
}
return result;
}
// 闰年判断
export function isLeapYear(year: number): boolean {
let result: boolean = false;
if ((year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0)) {
result = true;
} else {
result = false;
}
return result;
}
遇到的问题
首先我遇到项目中需要显示Toast弹窗,但是ArkTS好像准备弃用直接调用Toast方法,所以需要创建一个类用于显示Toast弹窗,于是我参考了官方的代码自定义了一个Toast弹窗的类,并且在需要的地方调用了类中自定义的ShowToast方法,但是在编译时一直报错,显示TypeError,类型错误,所以我接着检查了方法定义时需要输入的数值的类型,也检查了输出的数值类型,都是对应的,没有问题。最后通过AI的帮助我才发现其实是这个Toast类为undefined的原因,也就是在上述知识点中提到的空安全的问题,没有在调用前进行初始化,所以根据官方教程进行编写的话,记得在实例化类之前在entry > src > main > ets > entryability > EntryAbility.ets文件中的onWindowStageCreate函数中添加对应的类的初始化
遇到了输入框输入文字之后没有内容显示。第一次遇到这个问题时,我以为是文字颜色和背景色相同的问题,所以修改TextInput组件的.fontcolor属性,但是还是不显示并且在编译时没有报任何错误。后面经过不断的修改和尝试之后发现只是这个输入框组件高度和宽度的问题,所以导致输入框太小,被挡住或者看不清