HarmonyOS NEXT - ArkTS语言介绍 - 基本知识{声明、类型、运算符,语句}

ArkTS是一种为构建高性能应用而设计的编程语言。ArkTS在继承TypeScript语法的基础上进行了优化,以提供更高的性能和开发效率。

随着移动设备在人们的日常生活中变得越来越普遍,许多编程语言在设计之初没有考虑到移动设备,导致应用的运行缓慢、低效、功耗大,针对移动环境的编程语言优化需求也越来越大。ArkTS是专为解决这些问题而设计的,聚焦于提高运行效率。

目前流行的编程语言TypeScript是在JavaScript基础上通过添加类型定义扩展而来的,而ArkTS则是TypeScript的进一步扩展。TypeScript深受开发者的喜爱,因为它提供了一种更结构化的JavaScript编码方法。ArkTS旨在保持TypeScript的大部分语法,为现有的TypeScript开发者实现无缝过渡,让移动开发者快速上手ArkTS。

ArkTS的一大特性是它专注于低运行时开销。ArkTS对TypeScript的动态类型特性施加了更严格的限制,以减少运行时开销,提高执行效率。通过取消动态类型特性,ArkTS代码能更有效地被运行前编译和优化,从而实现更快的应用启动和更低的功耗。

与JavaScript的互通性是ArkTS语言设计中的关键考虑因素。鉴于许多移动应用开发者希望重用其TypeScript和JavaScript代码和库,ArkTS提供了与JavaScript的无缝互通,使开发者可以很容易地将JavaScript代码集成到他们的应用中。这意味着开发者可以利用现有的代码和库进行ArkTS开发。

为了确保应用开发的最佳体验,ArkTS提供对方舟开发框架ArkUI的声明式语法和其他特性的支持。由于此部分特性不在既有TypeScript的范围内,因此我们在《ArkUI支持》一章中提供了详细的ArkUI示例。

本教程将指导开发者了解ArkTS的核心功能、语法和最佳实践,使开发者能够使用ArkTS高效构建高性能的移动应用。

基本知识

声明

ArkTS通过声明引入变量、常量、函数和类型。

变量声明

以关键字let开头的声明引入变量,该变量在程序执行期间可以具有不同的值。
 

let hi: string = 'hello';
hi = 'hello, world';

常量声明

以关键字const开头的声明引入只读常量,该常量只能被赋值一次。

const hello: string = 'hello';

对常量重新赋值会造成编译时错误。

自动类型推断

由于ArkTS是一种静态类型语言,所有数据的类型都必须在编译时确定。

但是,如果一个变量或常量的声明包含了初始值,那么开发者就不需要显式指定其类型。ArkTS规范中列举了所有允许自动推断类型的场景。

以下示例中,两条声明语句都是有效的,两个变量都是string类型:
 

let hi1: string = 'hello';
let hi2 = 'hello, world';

类型

Number类型

ArkTS提供number和Number类型,任何整数和浮点数都可以被赋给此类型的变量。

数字字面量包括整数字面量和十进制浮点数字面量。

整数字面量包括以下类别:

  • 由数字序列组成的十进制整数。例如: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

浮点字面量包括以下:

  • 十进制整数,可为有符号数(即,前缀为“+”或“-”);
  • 小数点(“.”)
  • 小数部分(由十进制数字字符串表示)
  • 以“e”或“E”开头的指数部分,后跟有符号(即,前缀为“+”或“-”)或无符号整数。

示例:
 

let n1 = 3.14;
let n2 = 3.141592;
let n3 = .5;
let n4 = 1e10;

function factorial(n: number): number {
  if (n <= 1) {
    return 1;
  }
  return n * factorial(n - 1);
}

Boolean类型

boolean类型由true和false两个逻辑值组成。

通常在条件语句中使用boolean类型的变量:
 

let isDone: boolean = false;

// ...

if (isDone) {
  console.log ('Done!');
}

String类型

string代表字符序列;可以使用转义字符来表示字符。

字符串字面量由单引号(')或双引号(")之间括起来的零个或多个字符组成。字符串字面量还有一特殊形式,是用反向单引号(`)括起来的模板字面量。
 

let s1 = 'Hello, world!\n';
let s2 = 'this is a string';
let a = 'Success';
let s3 = `The result is ${a}`;

Void类型

void类型用于指定函数没有返回值。

此类型只有一个值,同样是void。由于void是引用类型,因此它可以用于泛型类型参数。
 

class Class<T> {
  //...
}
let instance: Class <void>

Object类型

Object类型是所有引用类型的基类型。任何值,包括基本类型的值(它们会被自动装箱),都可以直接被赋给Object类型的变量。

Array类型

array,即数组,是由可赋值给数组声明中指定的元素类型的数据组成的对象。

数组可由数组复合字面量(即用方括号括起来的零个或多个表达式的列表,其中每个表达式为数组中的一个元素)来赋值。数组的长度由数组中元素的个数来确定。数组中第一个元素的索引为0。

以下示例将创建包含三个元素的数组:
 

let names: string[] = ['Alice', 'Bob', 'Carol'];

Enum类型

enum类型,又称枚举类型,是预先定义的一组命名值的值类型,其中命名值又称为枚举常量。

使用枚举常量时必须以枚举类型名称为前缀。
 

enum ColorSet { Red, Green, Blue }
let c: ColorSet = ColorSet.Red;

常量表达式可以用于显式设置枚举常量的值。
 

enum ColorSet { White = 0xFF, Grey = 0x7F, Black = 0x00 }
let c: ColorSet = ColorSet.Black;

Union类型

union类型,即联合类型,是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型。
 

class Cat {
  // ...
}
class Dog {
  // ...
}
class Frog {
  // ...
}
type Animal = Cat | Dog | Frog | number
// Cat、Dog、Frog是一些类型(类或接口)

let animal: Animal = new Cat();
animal = new Frog();
animal = 42;
// 可以将类型为联合类型的变量赋值为任何组成类型的有效值

可以用不同的机制获取联合类型中特定类型的值。

示例:
 

class Cat { sleep () {}; meow () {} }
class Dog { sleep () {}; bark () {} }
class Frog { sleep () {}; leap () {} }

type Animal = Cat | Dog | Frog | number

let animal: Animal = new Frog();
if (animal instanceof Frog) {
  let frog: Frog = animal as Frog; // animal在这里是Frog类型
  animal.leap();
  frog.leap();
  // 结果:青蛙跳了两次
}

animal.sleep (); // 任何动物都可以睡觉

Aliases类型

Aliases类型为匿名类型(数组、函数、对象字面量或联合类型)提供名称,或为已有类型提供替代名称。
 

type Matrix = number[][];
type Handler = (s: string, no: number) => string;
type Predicate <T> = (x: T) => Boolean;
type NullableObject = Object | null;

运算符

赋值运算符

赋值运算符=,使用方式如x=y。

复合赋值运算符将赋值与运算符组合在一起,其中x op = y等于x = x op y。

复合赋值运算符列举如下:+=、-=、*=、/=、%=、<<=、>>=、>>>=、&=、|=、^=。

比较运算符

运算符

说明

==

如果两个操作数相等,则返回true。

!=

如果两个操作数不相等,则返回true。

>

如果左操作数大于右操作数,则返回true。

>=

如果左操作数大于或等于右操作数,则返回true。

<

如果左操作数小于右操作数,则返回true。

<=

如果左操作数小于或等于右操作数,则返回true。

算术运算符

一元运算符为-、+、--、++。

二元运算符列举如下:
 

运算符

说明

+

加法

-

减法

*

乘法

/

除法

%

除法后余数

位运算符

运算符

说明

a & b

按位与:如果两个操作数的对应位都为1,则将这个位设置为1,否则设置为0。

a | b

按位或:如果两个操作数的相应位中至少有一个为1,则将这个位设置为1,否则设置为0。

a ^ b

按位异或:如果两个操作数的对应位不同,则将这个位设置为1,否则设置为0。

~ a

按位非:反转操作数的位。

a << b

左移:将a的二进制表示向左移b位。

a >> b

算术右移:将a的二进制表示向右移b位,带符号扩展。

a >>> b

逻辑右移:将a的二进制表示向右移b位,左边补0。

逻辑运算符

运算符

说明

a && b

逻辑与

a || b

逻辑或

! a

逻辑非

语句

If语句

if语句用于需要根据逻辑条件执行不同语句的场景。当逻辑条件为真时,执行对应的一组语句,否则执行另一组语句(如果有的话)。

else部分也可能包含if语句。

if语句如下所示:
 

if (condition1) {
  // 语句1
} else if (condition2) {
  // 语句2
} else {
  // else语句
}

条件表达式可以是任何类型。但是对于boolean以外的类型,会进行隐式类型转换:
 

let s1 = 'Hello';
if (s1) {
  console.log(s1); // 打印“Hello”
}

let s2 = 'World';
if (s2.length != 0) {
  console.log(s2); // 打印“World”
}

Switch语句

使用switch语句来执行与switch表达式值匹配的代码块。

switch语句如下所示:
 

switch (expression) {
  case label1: // 如果label1匹配,则执行
    // ...
    // 语句1
    // ...
    break; // 可省略
  case label2:
  case label3: // 如果label2或label3匹配,则执行
    // ...
    // 语句23
    // ...
    break; // 可省略
  default:
    // 默认语句
}

如果switch表达式的值等于某个label的值,则执行相应的语句。

如果没有任何一个label值与表达式值相匹配,并且switch具有default子句,那么程序会执行default子句对应的代码块。

break语句(可选的)允许跳出switch语句并继续执行switch语句之后的语句。

如果没有break语句,则执行switch中的下一个label对应的代码块。

条件表达式

条件表达式由第一个表达式的布尔值来决定返回其它两个表达式中的哪一个。

示例如下:
 

condition ? expression1 : expression2

如果condition的为真值(转换后为true的值),则使用expression1作为该表达式的结果;否则,使用expression2。

示例:
 

let isValid = Math.random() > 0.5 ? true : false;
let message = isValid ? 'Valid' : 'Failed';

For语句

for语句会被重复执行,直到循环退出语句值为false。

for语句如下所示:
 

for ([init]; [condition]; [update]) {
  statements
}

for语句的执行流程如下:

1、 执行init表达式(如有)。此表达式通常初始化一个或多个循环计数器。

2、 计算condition。如果它为真值(转换后为true的值),则执行循环主体的语句。如果它为假值(转换后为false的值),则for循环终止。

3、 执行循环主体的语句。

4、 如果有update表达式,则执行该表达式。

5、 回到步骤2。

示例:
 

let sum = 0;
for (let i = 0; i < 10; i += 2) {
  sum += i;
}

For-of语句

使用for-of语句可遍历数组或字符串。示例如下:
 

for (forVar of expression) {
  statements
}

示例:
 

for (let ch of 'a string object') {
  /* process ch */
}

While语句

只要condition为真值(转换后为true的值),while语句就会执行statements语句。示例如下:
 

while (condition) {
  statements
}

示例:
 

let n = 0;
let x = 0;
while (n < 3) {
  n++;
  x += n;
}

Do-while语句

如果condition的值为真值(转换后为true的值),那么statements语句会重复执行。示例如下:
 

do {
  statements
} while (condition)

示例:
 

let i = 0;
do {
  i += 1;
} while (i < 10)

Break语句

使用break语句可以终止循环语句或switch。

示例:
 

let x = 0;
while (true) {
  x++;
  if (x > 5) {
    break;
  }
}

如果break语句后带有标识符,则将控制流转移到该标识符所包含的语句块之外。

示例:
 

let x = 1
label: while (true) {
  switch (x) {
    case 1:
      // statements
      break label // 中断while语句
  }
}

Continue语句

continue语句会停止当前循环迭代的执行,并将控制传递给下一个迭代。

示例:
 

let sum = 0;
for (let x = 0; x < 100; x++) {
  if (x % 2 == 0) {
    continue
  }
  sum += x;
}

Throw和Try语句

throw语句用于抛出异常或错误:
 

throw new Error('this error')

try语句用于捕获和处理异常或错误:
 

try {
  // 可能发生异常的语句块
} catch (e) {
  // 异常处理
}

下面的示例中throw和try语句用于处理除数为0的错误:
 

class ZeroDivisor extends Error {}

function divide (a: number, b: number): number{
  if (b == 0) throw new ZeroDivisor();
  return a / b;
}

function process (a: number, b: number) {
  try {
    let res = divide(a, b);
    console.log('result: ' + res);
  } catch (x) {
    console.log('some error');
  }
}

支持finally语句:
 

function processData(s: string) {
  let error: Error | null = null;

  try {
    console.log('Data processed: ' + s);
    // ...
    // 可能发生异常的语句
    // ...
  } catch (e) {
    error = e as Error;
    // ...
    // 异常处理
    // ...
  } finally {
    if (error != null) {
      console.log(`Error caught: input='${s}', message='${error.message}'`);
    }
  }
}

  • 20
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值