ArkTS基礎函數定義與調用

文章簡介

在HarmonyOS應用開發中,ArkTS作為基於TypeScript的擴展語言,函數是其核心編程概念之一。本文將系統講解ArkTS中函數的定義、參數傳遞、返回值處理等關鍵知識點,通過豐富的代碼示例幫助開發者掌握函數的使用技巧。

官方參考資料:

  • ArkTS語言官方文檔
  • ArkTS編程規範

函數定義基礎

基本函數定義語法

ArkTS中的函數定義遵循TypeScript語法規範,同時結合HarmonyOS特性進行了擴展。

// 最簡單的函數定義
function greet(): void {
  console.log('Hello, HarmonyOS!');
}

// 帶參數的函數
function calculateArea(width: number, height: number): number {
  return width * height;
}

// 箭頭函數
const multiply = (a: number, b: number): number => {
  return a * b;
};

函數定義的關鍵組成部分

  • function關鍵字:聲明一個函數
  • 函數名:遵循標識符命名規則
  • 參數列表:可接受零個或多個參數
  • 返回類型:指定函數返回值的數據類型
  • 函數體:包含具體執行邏輯的代碼塊

函數參數詳解

必需參數與可選參數

// 必需參數
function createUser(name: string, age: number): void {
  console.log(`用户: ${name}, 年齡: ${age}`);
}

// 可選參數(使用?標識)
function configureDevice(deviceName: string, timeout?: number): void {
  const actualTimeout = timeout || 3000;
  console.log(`配置設備: ${deviceName}, 超時: ${actualTimeout}ms`);
}

// 調用示例
createUser("張三", 25);        // 正確
configureDevice("智能音箱");    // timeout使用默認值
configureDevice("智能電視", 5000); // 指定timeout

默認參數值

// 帶默認值的參數
function connectWifi(ssid: string, password: string = "12345678"): boolean {
  console.log(`連接WiFi: ${ssid}, 密碼: ${password}`);
  return true;
}

// 調用示例
connectWifi("HomeNetwork");              // 使用默認密碼
connectWifi("OfficeNetwork", "office888"); // 指定密碼

剩餘參數

// 剩餘參數(可變參數)
function logSensorData(sensorType: string, ...readings: number[]): void {
  console.log(`傳感器類型: ${sensorType}`);
  readings.forEach((reading, index) => {
    console.log(`讀數${index + 1}: ${reading}`);
  });
}

// 調用示例
logSensorData("温度傳感器", 25.6, 26.1, 24.8);
logSensorData("濕度傳感器", 65, 68);

返回值處理

基本返回值

// 返回基本類型
function getDeviceInfo(): string {
  return "HarmonyOS Device v2.0";
}

// 返回對象
function createCoordinate(x: number, y: number): {x: number, y: number} {
  return { x, y };
}

// 返回數組
function getSupportedResolutions(): number[] {
  return [720, 1080, 1440, 2160];
}

異步函數與Promise返回

// 異步函數定義
async function fetchNetworkData(url: string): Promise<string> {
  // 模擬網絡請求
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(`從 ${url} 獲取的數據`);
    }, 1000);
  });
}

// 使用async/await調用
async function loadData(): Promise<void> {
  try {
    const data = await fetchNetworkData("https://api.example.com/data");
    console.log("獲取到的數據:", data);
  } catch (error) {
    console.error("數據獲取失敗:", error);
  }
}

函數類型與高級特性

函數類型註解

// 定義函數類型
type MathOperation = (a: number, b: number) => number;

// 使用函數類型
const add: MathOperation = (x, y) => x + y;
const subtract: MathOperation = (x, y) => x - y;

// 函數作為參數
function calculate(a: number, b: number, operation: MathOperation): number {
  return operation(a, b);
}

// 調用示例
const result1 = calculate(10, 5, add);      // 15
const result2 = calculate(10, 5, subtract); // 5

函數重載

// 函數重載聲明
function processInput(input: string): string;
function processInput(input: number): number;
function processInput(input: boolean): boolean;

// 函數實現
function processInput(input: any): any {
  if (typeof input === 'string') {
    return input.toUpperCase();
  } else if (typeof input === 'number') {
    return input * 2;
  } else if (typeof input === 'boolean') {
    return !input;
  }
}

// 調用示例
console.log(processInput("hello")); // "HELLO"
console.log(processInput(10));      // 20
console.log(processInput(true));    // false

函數調用實踐

基本調用方式

// 直接調用
function showNotification(message: string): void {
  console.log(`通知: ${message}`);
}

showNotification("系統更新完成");

// 方法調用(作為對象屬性)
const deviceUtils = {
  getBatteryLevel: (): number => {
    return 85; // 模擬電池電量
  },
  restart: (): void => {
    console.log("設備重啓中...");
  }
};

const battery = deviceUtils.getBatteryLevel();
deviceUtils.restart();

回調函數使用

// 定義回調函數類型
type OperationCallback = (result: number) => void;

// 使用回調函數
function complexCalculation(
  values: number[], 
  callback: OperationCallback
): void {
  let sum = 0;
  for (const value of values) {
    sum += value;
  }
  callback(sum);
}

// 調用帶回調的函數
complexCalculation([1, 2, 3, 4, 5], (result) => {
  console.log(`計算結果: ${result}`);
});

立即執行函數(IIFE)

// 立即執行函數
const appConfig = (() => {
  const config = {
    version: "1.0.0",
    apiEndpoint: "https://api.harmonyos.com",
    timeout: 5000
  };
  
  // 返回配置對象的只讀副本
  return Object.freeze(config);
})();

console.log(`應用版本: ${appConfig.version}`);

實際應用案例

HarmonyOS組件中的函數使用

@Entry
@Component
struct DeviceController {
  @State deviceStatus: string = 'offline';
  
  // 組件內的方法
  private toggleDevice(): void {
    this.deviceStatus = this.deviceStatus === 'online' ? 'offline' : 'online';
    console.log(`設備狀態切換為: ${this.deviceStatus}`);
  }
  
  // 帶參數的方法
  private setDeviceBrightness(level: number): void {
    if (level < 0 || level > 100) {
      console.error('亮度值必須在0-100之間');
      return;
    }
    console.log(`設置設備亮度為: ${level}%`);
  }
  
  build() {
    Column() {
      Text(`設備狀態: ${this.deviceStatus}`)
        .fontSize(20)
      
      Button('切換狀態')
        .onClick(() => {
          this.toggleDevice();
        })
      
      Button('設置亮度為50%')
        .onClick(() => {
          this.setDeviceBrightness(50);
        })
    }
    .padding(20)
    .width('100%')
  }
}

工具函數集合示例

// 設備工具函數集合
class DeviceUtils {
  // 靜態方法 - 不需要實例化即可調用
  static validateMacAddress(mac: string): boolean {
    const macRegex = /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/;
    return macRegex.test(mac);
  }
  
  // 實例方法
  formatStorageSize(bytes: number): string {
    const units = ['B', 'KB', 'MB', 'GB'];
    let size = bytes;
    let unitIndex = 0;
    
    while (size >= 1024 && unitIndex < units.length - 1) {
      size /= 1024;
      unitIndex++;
    }
    
    return `${size.toFixed(2)} ${units[unitIndex]}`;
  }
}

// 使用示例
const isValid = DeviceUtils.validateMacAddress("00:1B:44:11:3A:B7");
console.log(`MAC地址驗證結果: ${isValid}`);

const utils = new DeviceUtils();
const formattedSize = utils.formatStorageSize(15483264);
console.log(`格式化存儲大小: ${formattedSize}`);

參數配置表格

常用函數參數選項

參數類型

語法示例

適用場景

注意事項

必需參數

(name: string)

函數必須的參數

調用時必須提供

可選參數

(timeout?: number)

可選的配置參數

使用前檢查undefined

默認參數

(retries: number = 3)

有默認值的參數

默認值在函數定義時計算

剩餘參數

(...values: number[])

數量不定的參數

在函數內作為數組使用

對象參數

(config: {url: string, method: string})

複雜的配置選項

建議使用接口定義類型

函數修飾符比較

修飾符

示例

作用

使用場景

async

async function fetchData()

聲明異步函數

需要await操作的函數

private

private init()

私有方法

類內部使用的方法

static

static create()

靜態方法

不需要實例化的工具方法

readonly

readonly config

只讀屬性

不希望被修改的配置

注意事項與最佳實踐

⚠️ 重要提示

版本兼容性説明:

  • 本文代碼基於HarmonyOS 4.0+ 和 ArkTS 3.0+
  • 異步函數語法需要API version 8+
  • 函數類型註解需要完整的TypeScript支持

常見陷阱與解決方案:

// ❌ 錯誤示例:可選參數在必需參數之前
function badExample(optionalParam?: string, requiredParam: string): void {
  // 這會導致編譯錯誤
}

// ✅ 正確示例:必需參數在前,可選參數在後
function goodExample(requiredParam: string, optionalParam?: string): void {
  console.log(requiredParam, optionalParam);
}

// ❌ 錯誤示例:箭頭函數中的this指向問題
class ProblematicClass {
  value: number = 10;
  
  problematicMethod(): void {
    setTimeout(() => {
      console.log(this.value); // 可能無法正確訪問this
    }, 1000);
  }
}

// ✅ 正確示例:使用普通函數或綁定this
class CorrectClass {
  value: number = 10;
  
  correctMethod(): void {
    setTimeout(() => {
      console.log(this.value); // 箭頭函數捕獲外層this
    }, 1000);
  }
}

性能優化建議

  1. 避免在渲染函數中定義函數
// ❌ 不推薦:每次渲染都會創建新函數
build() {
  const handleClick = () => { /* ... */ };
  return Button('點擊').onClick(handleClick);
}

// ✅ 推薦:使用類方法或useCallback
private handleClick = (): void => { /* ... */ };
build() {
  return Button('點擊').onClick(this.handleClick);
}
  1. 合理使用函數記憶化
// 使用緩存優化計算密集型函數
const memoizedCalculation = (() => {
  const cache = new Map<string, number>();
  
  return (input: string): number => {
    if (cache.has(input)) {
      return cache.get(input)!;
    }
    
    // 複雜計算
    const result = /* 計算邏輯 */;
    cache.set(input, result);
    return result;
  };
})();

實戰練習步驟

練習:創建設備管理工具函數

步驟1:定義基礎函數

// 設備狀態管理函數
function validateDeviceId(deviceId: string): boolean {
  return deviceId.length >= 5 && deviceId.length <= 32;
}

function generateDeviceToken(prefix: string = "DEV"): string {
  const timestamp = new Date().getTime();
  const random = Math.random().toString(36).substring(2, 8);
  return `${prefix}_${timestamp}_${random}`;
}

步驟2:創建配置管理函數

interface DeviceConfig {
  name: string;
  type: 'sensor' | 'actuator' | 'controller';
  pollingInterval?: number;
  retryCount?: number;
}

function createDeviceConfig(
  name: string, 
  type: DeviceConfig['type'],
  options: { pollingInterval?: number, retryCount?: number } = {}
): DeviceConfig {
  return {
    name,
    type,
    pollingInterval: options.pollingInterval || 5000,
    retryCount: options.retryCount || 3
  };
}

步驟3:實現批量操作函數

async function batchDeviceOperation(
  deviceIds: string[],
  operation: (deviceId: string) => Promise<boolean>
): Promise<{ success: string[], failed: string[] }> {
  const success: string[] = [];
  const failed: string[] = [];
  
  for (const deviceId of deviceIds) {
    try {
      const result = await operation(deviceId);
      if (result) {
        success.push(deviceId);
      } else {
        failed.push(deviceId);
      }
    } catch (error) {
      failed.push(deviceId);
      console.error(`設備 ${deviceId} 操作失敗:`, error);
    }
  }
  
  return { success, failed };
}

步驟4:測試函數功能

// 測試代碼
async function testDeviceFunctions(): Promise<void> {
  // 測試設備ID驗證
  console.log('設備ID驗證:', validateDeviceId('my_device_001'));
  
  // 測試令牌生成
  console.log('設備令牌:', generateDeviceToken());
  
  // 測試配置創建
  const config = createDeviceConfig('温度傳感器', 'sensor', { pollingInterval: 3000 });
  console.log('設備配置:', config);
  
  // 測試批量操作
  const results = await batchDeviceOperation(
    ['dev1', 'dev2', 'dev3'],
    async (id) => {
      // 模擬設備操作
      return Math.random() > 0.3; // 70%成功率
    }
  );
  
  console.log('批量操作結果:', results);
}

總結

通過本文的學習,你應該掌握了:

  • ✅ ArkTS函數的基本定義語法和調用方式
  • ✅ 各種參數類型的正確使用方法
  • ✅ 函數返回值的處理和類型註解
  • ✅ 高級函數特性如重載、回調、異步函數
  • ✅ 在HarmonyOS組件中合理使用函數
  • ✅ 函數性能優化和最佳實踐

函數是ArkTS編程的基礎,熟練掌握函數的使用能夠大大提高HarmonyOS應用開發的效率和質量。建議在實際開發中多加練習,逐步掌握更多高級函數技巧。


擴展學習資源:

  • ArkTS官方編程指南
  • HarmonyOS API參考
  • TypeScript函數手冊

本文最後更新於2024年,基於HarmonyOS 4.0和ArkTS 3.0版本。隨着技術發展,部分API可能會有更新,請以官方最新文檔為準。