鸿蒙原生开发手记:徒步迹 - ArkTS 语法快速入门

掌握 ArkTS 核心语法,为开发"徒步迹"打好语言基础


一、前言

ArkTS 是鸿蒙原生应用的主要开发语言,它是 TypeScript 的超集,在 TypeScript 的基础上增加了静态类型检查和声明式 UI 编程的支持。与标准的 TypeScript 相比,ArkTS 有以下特点:

  • 严格类型检查:所有变量必须有明确的类型
  • 装饰器语法:使用 @Component@State 等装饰器来定义组件和状态
  • 数据绑定:声明式 UI 与状态管理深度集成
  • 性能优化:AOT 编译到原生机器码,运行时零反射

本文将结合"徒步迹"App 的实际需求,快速带你掌握 ArkTS 的核心语法。


二、变量与类型声明

ArkTS 要求所有变量必须有明确的类型声明,不支持隐式的 any 类型。

2.1 基础类型

// 数值类型
let distance: number = 5.2;        // 徒步距离(km)
let elevation: number = 300;       // 爬升高度(m)
let steps: number = 8642;          // 步数

// 字符串类型
let routeName: string = '山野徒步路线';
let description: string = '这是一条风景优美的路线';

// 布尔类型
let isRecording: boolean = false;   // 是否在记录中
let isPublic: boolean = true;       // 是否公开

// 联合类型
let status: 'idle' | 'recording' | 'paused' | 'completed' = 'idle';

2.2 数组与元组

// 数组 - 存储轨迹点坐标
let coordinates: number[] = [116.397, 39.908, 116.398, 39.909];
let routeNames: string[] = ['路线A', '路线B', '路线C'];

// 泛型数组
let trackPoints: Array<number> = [];

// 元组 - 固定长度和类型
let coordinatePair: [number, number] = [116.397, 39.908];

2.3 对象与接口

使用 interface 定义数据模型,这是 ArkTS 中最重要的类型定义方式:

interface HikingRoute {
  id: number;
  name: string;
  distance: number;
  duration: number;
  difficulty: '简单' | '中等' | '困难';
  tags: string[];
}

// 使用接口
let route: HikingRoute = {
  id: 1,
  name: '香山徒步',
  distance: 8.5,
  duration: 5400,  // 秒
  difficulty: '中等',
  tags: ['森林', '山景'],
};

三、函数定义

ArkTS 中的函数定义需明确参数类型和返回值类型:

// 基础函数
function calculatePace(duration: number, distance: number): number {
  return duration / distance;
}

// 箭头函数
const formatDistance = (meters: number): string => {
  if (meters >= 1000) {
    return `${(meters / 1000).toFixed(2)} km`;
  }
  return `${Math.round(meters)} m`;
};

// 可选参数
function createRoute(name: string, description?: string): HikingRoute {
  return {
    id: Date.now(),
    name: name,
    distance: 0,
    duration: 0,
    difficulty: '简单',
    tags: [],
  };
}

// 使用
let route1 = createRoute('周末徒步');
let route2 = createRoute('越野训练', '适合有经验者');

四、类与装饰器

ArkTS 中类的使用与传统 TypeScript 类似,但加入了装饰器语法用于声明式 UI。

4.1 普通类

class RouteService {
  private routes: HikingRoute[] = [];

  addRoute(route: HikingRoute): void {
    this.routes.push(route);
  }

  getRouteById(id: number): HikingRoute | undefined {
    return this.routes.find(r => r.id === id);
  }

  get totalDistance(): number {
    return this.routes.reduce((sum, r) => sum + r.distance, 0);
  }
}

// 使用
const service = new RouteService();
service.addRoute(route1);
console.log(service.totalDistance);

4.2 组件装饰器

这是 ArkTS 最核心的特性 - 用装饰器定义 UI 组件:

@Component
struct RouteCard {
  @Prop routeName: string = '';
  @Prop distance: number = 0;

  build() {
    Column() {
      Text(this.routeName)
        .fontSize(16)
        .fontWeight(FontWeight.Bold);
      Text(`距离: ${this.distance}km`)
        .fontSize(14)
        .fontColor('#666');
    }
    .padding(12)
    .backgroundColor('#FFF')
    .borderRadius(8);
  }
}

五、控制流语句

// if/else
function getDifficulty(distance: number): string {
  if (distance < 5) {
    return '简单';
  } else if (distance < 15) {
    return '中等';
  } else {
    return '困难';
  }
}

// for-of 循环(推荐)
let tags: string[] = ['森林', '山景', '溪流'];
for (let tag of tags) {
  console.log(tag);
}

// forEach
routes.forEach((route, index) => {
  console.log(`${index}: ${route.name}`);
});

ArkTS 不支持 for-in 循环,推荐使用 for-of 或数组方法。


六、异步编程

ArkTS 使用 async/await 处理异步操作,与标准 TypeScript 一致:

// 模拟网络请求
async function fetchRoutes(): Promise<HikingRoute[]> {
  // 返回 Promise
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve([route1, route2]);
    }, 1000);
  });
}

// 使用 async/await
async function loadRoutes(): Promise<void> {
  try {
    const routes = await fetchRoutes();
    console.log(`加载了 ${routes.length} 条路线`);
  } catch (error) {
    console.error('加载失败:', error);
  }
}

七、模块化

ArkTS 使用 import/export 进行模块化管理:

// ---- models/Route.ets ----
export interface HikingRoute {
  id: number;
  name: string;
}

export function formatRouteName(name: string): string {
  return `徒步 - ${name}`;
}

// ---- pages/RouteList.ets ----
import { HikingRoute, formatRouteName } from '../models/Route';

const route: HikingRoute = { id: 1, name: '香山' };
console.log(formatRouteName(route.name)); // 输出: 徒步 - 香山

八、与 TypeScript 的主要区别

特性 TypeScript ArkTS
any 类型 支持 不支持
unknown 类型 支持 不支持
as 类型断言 支持 不支持(用 as T 受限)
for-in 支持 不支持
装饰器 实验性 原生支持
声明式 UI 无内置支持 内置 ArkUI 框架
JSDoc 类型注释 支持 不支持

九、实战:徒步迹数据模型

结合"徒步迹"App,我们定义核心数据模型:

// models/DataModels.ets

export interface User {
  id: number;
  nickname: string;
  avatar: string;
  phone: string;
}

export interface Coordinate {
  latitude: number;
  longitude: number;
  altitude: number;
  timestamp: number;
}

export interface Recording {
  id: number;
  name: string;
  startTime: number;
  endTime: number;
  distance: number;
  duration: number;
  calories: number;
  trackPoints: Coordinate[];
  status: 'idle' | 'recording' | 'paused' | 'completed';
}

export interface Team {
  id: number;
  name: string;
  memberCount: number;
  maxMembers: number;
}

// 工具函数
export function calculateDistance(
  coord1: Coordinate,
  coord2: Coordinate
): number {
  const R = 6371000; // 地球半径
  const dLat = (coord2.latitude - coord1.latitude) * Math.PI / 180;
  const dLon = (coord2.longitude - coord1.longitude) * Math.PI / 180;
  const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(coord1.latitude * Math.PI / 180) *
    Math.cos(coord2.latitude * Math.PI / 180) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
  return R * c;
}

这个数据模型将在后续所有页面开发中反复使用。


十、总结

通过本文,我们学习了 ArkTS 的核心语法,包括类型系统、函数、类、装饰器、异步编程和模块化等关键特性。与 TypeScript 相比,ArkTS 更加严格但也更安全,特别适合声明式 UI 开发。

下一篇文章我们将学习 ArkUI 框架的基础组件,开始构建"徒步迹"的用户界面。


下一篇预告:鸿蒙原生开发手记:徒步迹 - ArkUI 声明式UI基础组件

有任何疑问欢迎在评论区留言,我们一起交流学习。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐