[文章]基于凌羽派的OpenHarmony北向应用开发:ArkTS语法-数据类型和变量声明

阅读量0
0
0

一、简介

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

环境配置如下所示:

二、基础知识

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

2.1 变量声明

使用关键字let声明的变量可以在程序执行期间具有不同的值。使用TS风格,声明的时候使用冒号给出数据类型。

let hi: string = 'hello';
let num: number = 0;

2.2 常量声明

使用关键字const声明的常量为只读类型,只能被赋值一次。

const hello: string = 'hello';

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

2.3 自动类型推断

如果变量或常量的声明包含初始值,开发者无需显式指定类型,因为ArkTS规范已列举了所有允许自动推断类型的场景。

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

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

2.4 数据类型

基本数据类型包括number、string等简单类型,它们可以准确地表示单一的数据类型。对基本类型的存储和访问都是直接的,比较时直接比较其值。

引用类型包括对象、数组和函数等复杂数据结构。这些类型通过引用访问数据,对象和数组可以包含多个值或键值对,函数则可以封装可执行的代码逻辑。引用类型在内存中通过指针访问数据,修改引用会影响原始数据。

2.4.1 number类型

ArkTS提供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 = 1e2;
​
function factorial(n: number): number {
  if (n <= 1) {
    return 1;
  }
  return n * factorial(n - 1);
}
​
factorial(n1)  //  7.660344000000002 
factorial(n2)  //  7.680640444893748 
factorial(n3)  //  1 
factorial(n4)  //  9.33262154439441e+157

number类型在表示大整数(即超过-9007199254740991~9007199254740991)时会造成精度丢失。在开发时可以按需使用bigint类型来确保精度:

let bigInt: BigInt = BigInt('999999999999999999999999999999999999999999999999999999999999');
console.info('bigInt:' + bigInt.toString());

2.4.2 boolean类型

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

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

let isDone: boolean = false;
​
// ...if (isDone) {
  console.info('Done!');
}

2.4.3 string类型

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

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

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

2.4.4 void类型

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

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

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

2.4.5 Object类型

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

let o1: Object = 'Alice';
let o2: Object = ['a','b'];
let o3: Object = 1;

2.4.6 array类型

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

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

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

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

2.4.7 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;

2.4.8 Union类型

Union类型,即联合类型,是由多个类型组合成的引用类型。联合类型包含了变量可能的所有类型。使用type关键字进行定义。

class Cat {
  name: string = 'cat';
  // ...
}
class Dog {
  name: string = 'dog';
  // ...
}
class Frog {
  name: string = 'frog';
  // ...
}
type Animal = Cat | Dog | Frog | number | string | null | undefined;
// Cat、Dog、Frog是一些类型(类或接口)let animal: Animal = new Cat();
animal = new Frog();
animal = 42;
animal = 'dog';
animal = undefined;

// 可以将类型为联合类型的变量赋值为任何组成类型的有效值**可以使用不同机制获取联合类型中的特定类型值。

示例:

class Cat { sleep () {}; meow () {} }
class Dog { sleep () {}; bark () {} }
class Frog { sleep () {}; leap () {} }
​
type Animal = Cat | Dog | Frog;
​
function foo(animal: Animal) {
  if (animal instanceof Frog) {
    animal.leap();  // animal在这里是Frog类型
  }
  animal.sleep(); // Animal具有sleep方法
}

2.4.9 Aliases类型

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

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

三、代码讲解

下面是一个综合案例,演示了上述大部分知识点的实际应用。

3.1 任务一:变量声明与基本数据类型

这个任务将展示如何声明和使用各种基本数据类型的变量和常量。

// ======== 任务一:变量声明与基本数据类型 ========// 1. 使用 let 声明可变变量,并进行类型注解
let studentName: string = "张三";
let age: number = 20;
let isEnrolled: boolean = true;
​
// 2. 使用 const 声明常量(不可修改)
const MAX_STUDENTS: number = 100;
const COURSE_NAME: string = "HarmonyOS应用开发";
​
// 3. 类型推断 - 不显式写类型,让编译器自动推断
let city = "北京"; // 推断为 string
let score = 95.5;   // 推断为 number
let isActive = false; // 推断为 boolean// 4. 特殊类型:undefined 和 null
let uninitializedVar: undefined = undefined;
let emptyValue: null = null;
​
// 5. 在控制台输出所有变量及其类型
console.log("=== 基本数据类型练习 ===");
// typeof 操作符可以获取变量的类型
console.log(`学生姓名: ${studentName}, 类型: ${typeof studentName}`);
console.log(`年龄: ${age}, 类型: ${typeof age}`);
console.log(`是否注册: ${isEnrolled}, 类型: ${typeof isEnrolled}`);
console.log(`最大人数限制: ${MAX_STUDENTS}, 类型: ${typeof MAX_STUDENTS}`);
console.log(`课程名称: ${COURSE_NAME}, 类型: ${typeof COURSE_NAME}`);
console.log(`所在城市: ${city}, 类型: ${typeof city}`);
console.log(`分数: ${score}, 类型: ${typeof score}`);
console.log(`是否活跃: ${isActive}, 类型: ${typeof isActive}`);
console.log(`未初始化变量: ${uninitializedVar}, 类型: ${typeof uninitializedVar}`);
console.log(`空值: ${emptyValue}, 类型: ${typeof emptyValue}`);
​
// 尝试修改常量的值 (取消注释下面一行会报错)
// MAX_STUDENTS = 120;

3.2 任务二:数组与对象

这个任务将展示如何使用数组(Array)和对象(Object)来组织和管理更复杂的数据。我们还会引入 interface 来定义自定义的数据结构。

// ======== 任务二:数组与对象 ========// 1. 数组声明 - 使用类型注解
// 字符串数组
let favoriteSubjects: string[] = ["数学", "物理", "信息技术"];
// 数字数组
let testScores: number[] = [88, 92, 76, 95];
​
// 2. 对象声明 - 定义学生信息
// 使用 interface 定义一个自定义类型,增强代码可读性和类型检查
interface Contact {
  phone: string;
  email: string;
}
​
// 定义一个更复杂的 StudentInfo 类型
interface StudentInfo {
  id: number;
  name: string;
  age: number;
  grades: number[];   //  grades 属性是一个数字数组
  hobbies: string[];  //  hobbies 属性是一个字符串数组
  contact?: Contact;  //  contact 是一个可选属性,使用 ? 标记
}
​
// 根据 interface 创建一个学生对象
let student1: StudentInfo = {
  id: 1001,
  name: "王五",
  age: 19,
  grades: [85, 90, 88],
  hobbies: ["编程", "篮球", "音乐"]
  // contact 属性可以暂时不提供
};
​
// 3. 访问和修改对象属性
student1.age = 20; // 修改年龄
student1.hobbies.push("绘画"); // 向 hobbies 数组添加一个新元素// 4. 给对象添加可选的联系信息
student1.contact = {
  phone: "13800138000",
  email: "wangwu@example.com"
};
​
// 5. 数组方法练习
testScores.push(89); // 向 testScores 数组添加一个新成绩
// 使用扩展运算符 (...) 和 Math.max 函数找出最高分
let highestScore = Math.max(...testScores); 
​
// 6. 输出复杂类型数据
console.log("\\n=== 数组与对象练习 ===");
console.log("最喜欢的科目:", favoriteSubjects);
console.log("测试成绩:", testScores);
console.log("最高分:", highestScore);
​
console.log("学生信息:");
console.log(`ID: ${student1.id}`);
console.log(`姓名: ${student1.name}`);
console.log(`年龄: ${student1.age}`);
// 使用数组的 join 方法将数组转为字符串
console.log(`成绩: ${student1.grades.join(", ")}`);
console.log(`爱好: ${student1.hobbies.join(", ")}`);
​
// 安全地访问可选属性
if (student1.contact) {
  console.log(`电话: ${student1.contact.phone}`);
  console.log(`邮箱: ${student1.contact.email}`);
} else {
  console.log("联系方式: 未提供");
}

3.3 UI 展示组件

最后,我们将所有定义的数据在 UI 界面上展示出来。

@Entry
@Component
struct MainPage {
​
  build() {
    // 使用 Scroll 组件允许在内容超出屏幕时滚动
    Scroll() {
      // Column 组件将子元素垂直排列
      Column({ space: 10 }) {
        // --- 显示基本类型信息 ---
        Text('=== 基本数据类型演示 ===')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
​
        Text(`学生姓名: ${studentName}`)
        Text(`年龄: ${age}`)
        // 使用三元运算符将布尔值转为易读的文本
        Text(`是否注册: ${isEnrolled ? '是' : '否'}`)
        Text(`课程名称: ${COURSE_NAME}`)
        Text(`所在城市: ${city}`)
        Text(`分数: ${score}`)
        Text(`是否活跃: ${isActive ? '是' : '否'}`)
        Text(`最大人数限制: ${MAX_STUDENTS}`)
​
        // --- 显示复杂类型信息 ---
        Text('\\n=== 数组与对象演示 ===')
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
​
        Text(`最喜欢科目: ${favoriteSubjects.join(', ')}`)
        Text(`测试成绩: ${testScores.join(', ')}`)
        Text(`最高分: ${highestScore}`)
​
        Text('\\n--- 学生信息 ---')
        Text(`ID: ${student1.id}`)
        Text(`姓名: ${student1.name}`)
        Text(`年龄: ${student1.age}`)
        Text(`成绩: ${student1.grades.join(', ')}`)
        Text(`爱好: ${student1.hobbies.join(', ')}`)
​
        // 同样,在UI中安全地访问可选属性
        if (student1.contact) {
          Text(`电话: ${student1.contact.phone}`)
          Text(`邮箱: ${student1.contact.email}`)
        } else {
          Text("联系方式: 未提供")
        }
​
        // 添加一个空白组件,将内容与底部拉开距离
        Blank()
​
      }
      // 设置 Column 的宽度为父容器的 90%
      .width('90%')
      // 设置内边距
      .padding(10)
    }
  }
}

四、运行结果

:在开始本项目前,请参照 DevEco Studio开发环境搭建 完成环境搭建。

完成项目编译后,在 entry 目录下会出现 build 文件夹,参照下图步骤将应用安装到设备或模拟器:
down.png

dowm2.png

down3.png

结果
r1.png

r2.png

回帖

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
链接复制成功,分享给好友