HarmonyOS ArkTS 类型转换机制深度解析

引言

在HarmonyOS应用开发中,类型转换是一项基础而核心的技术能力。无论是处理用户输入、解析网络数据还是进行数据展示,都离不开类型转换。ArkTS作为HarmonyOS的主力开发语言,提供了强类型的类型系统,对类型转换有着严格的要求和独特的实现方式。本文将深入分析ArkTS中各种数据类型转换的实现原理,探讨类型安全策略和性能优化方法。


一、类型转换概述

1.1 为什么需要类型转换

在应用开发过程中,类型转换无处不在:

  • 用户输入处理:表单输入通常以字符串形式获取,需要转换为数字、布尔等类型
  • 数据持久化:将应用数据存储到本地或上传到服务器时的格式转换
  • API数据处理:后端返回的数据往往是字符串或JSON格式,需要转换为应用内部类型
  • UI数据展示:将数字、日期等数据转换为用户友好的显示格式

1.2 ArkTS类型系统特点

ArkTS基于TypeScript的静态类型系统,具有以下特点:

  • 强类型:每个变量都有明确的类型,类型转换需要显式进行
  • 编译时检查:大部分类型错误在编译阶段就能发现
  • 无隐式转换:不允许像JavaScript那样的隐式类型转换
  • 严格的null检查:所有可能为null的值都需要显式声明

1.3 类型转换接口设计

在ArkTS中,类型转换函数的返回值通常采用统一的结果接口:

typescript 复制代码
export interface ConvertResult {
  success: boolean;
  value: string;
  error?: string;
}

这种设计带来了以下优势:

  • 明确区分成功和失败状态
  • 错误信息清晰,便于调试
  • 调用方可以根据success字段决定后续逻辑
  • 统一的接口便于扩展和维护

二、字符串与数字转换

2.1 字符串转数字

字符串转数字是最常见的转换场景,主要使用JavaScript的原生方法:

typescript 复制代码
export function stringToNumber(value: string): ConvertResult {
  const num = parseFloat(value);
  if (isNaN(num)) {
    return { success: false, value: '', error: '无法转换为数字' };
  }
  return { success: true, value: num.toString() };
}

关键点分析

  • parseFloat():解析字符串,返回浮点数
  • isNaN():检查解析结果是否为NaN(Not a Number)
  • 返回字符串形式的结果,便于后续处理和展示

使用场景

typescript 复制代码
// 表单输入金额
@Local amountInput: string = '';
@Local amount: number = 0;

build() {
  TextInput({ placeholder: '请输入金额' })
    .onChange((value: string) => {
      this.amountInput = value;
      const result = stringToNumber(value);
      if (result.success) {
        this.amount = parseFloat(result.value);
      }
    })
}

2.2 数字转字符串

数字转字符串相对简单,主要用于显示和传输:

typescript 复制代码
export function numberToString(value: string): ConvertResult {
  const num = parseFloat(value);
  if (isNaN(num)) {
    return { success: false, value: '', error: '无效的数字' };
  }
  return { success: true, value: num.toString() };
}

注意事项

  • 直接使用toString()方法即可
  • 可以指定小数位数:num.toFixed(2)
  • 科学计数法转换:num.toExponential()

2.3 parseInt与parseFloat的选择

typescript 复制代码
// 使用parseInt解析整数
const intValue = parseInt('123'); // 123
const intHex = parseInt('0xFF', 16); // 255,支持进制解析

// 使用parseFloat解析浮点数
const floatValue = parseFloat('3.14'); // 3.14
const floatWithUnit = parseFloat('100px'); // 100,会忽略非数字后缀

最佳实践

  • 需要整数时使用parseInt(),并指定进制
  • 需要浮点数时使用parseFloat()
  • 始终使用isNaN()检查解析结果

三、字符串与布尔转换

3.1 字符串转布尔

ArkTS中没有隐式的字符串到布尔转换,需要手动实现:

typescript 复制代码
export function stringToBoolean(value: string): ConvertResult {
  const lower = value.toLowerCase().trim();
  if (lower === 'true' || lower === '1' || lower === 'yes') {
    return { success: true, value: 'true' };
  }
  if (lower === 'false' || lower === '0' || lower === 'no') {
    return { success: true, value: 'false' };
  }
  return { success: false, value: '', error: '无法转换为布尔值' };
}

转换规则

输入 输出
'true', 'True', 'TRUE' true
'1', 'yes', 'Yes' true
'false', 'False', 'FALSE' false
'0', 'no', 'No' false
其他 错误

3.2 布尔转字符串

typescript 复制代码
export function booleanToString(value: string): ConvertResult {
  const lower = value.toLowerCase().trim();
  if (lower === 'true' || lower === 'false') {
    return { success: true, value: lower };
  }
  return { success: false, value: '', error: '无效的布尔值' };
}

3.3 实际应用场景

typescript 复制代码
// 配置开关转换
interface AppConfig {
  darkMode: boolean;
  notifications: boolean;
  autoSave: boolean;
}

function parseConfig(raw: Record<string, string>): AppConfig {
  return {
    darkMode: stringToBoolean(raw.darkMode || 'false').value === 'true',
    notifications: stringToBoolean(raw.notifications || 'true').value === 'true',
    autoSave: stringToBoolean(raw.autoSave || 'false').value === 'true'
  };
}

四、日期时间转换

4.1 字符串转日期

日期转换是应用中非常常见的需求:

typescript 复制代码
export function stringToDate(value: string): ConvertResult {
  const date = new Date(value);
  if (isNaN(date.getTime())) {
    return { success: false, value: '', error: '无效的日期格式' };
  }
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  const hours = date.getHours().toString().padStart(2, '0');
  const minutes = date.getMinutes().toString().padStart(2, '0');
  const seconds = date.getSeconds().toString().padStart(2, '0');
  return { success: true, value: `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` };
}

关键点

  • 使用new Date()构造函数解析字符串
  • 通过isNaN(date.getTime())验证日期有效性
  • getTime()返回从1970年1月1日至今的毫秒数
  • 使用padStart()补零确保两位数格式

4.2 时间戳转换

时间戳是后端常用的日期表示方式:

typescript 复制代码
export function stringToTimestamp(value: string): ConvertResult {
  const date = new Date(value);
  if (isNaN(date.getTime())) {
    return { success: false, value: '', error: '无效的日期格式' };
  }
  return { success: true, value: date.getTime().toString() };
}

export function timestampToString(value: string): ConvertResult {
  const timestamp = parseInt(value);
  if (isNaN(timestamp)) {
    return { success: false, value: '', error: '无效的时间戳' };
  }
  const date = new Date(timestamp);
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  const hours = date.getHours().toString().padStart(2, '0');
  const minutes = date.getMinutes().toString().padStart(2, '0');
  const seconds = date.getSeconds().toString().padStart(2, '0');
  return { success: true, value: `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` };
}

4.3 日期格式化模板

灵活的日期格式化是提升用户体验的关键:

typescript 复制代码
export function formatDate(date: Date, format: string = 'YYYY-MM-DD'): string {
  const year = date.getFullYear();
  const month = date.getMonth() + 1;
  const day = date.getDate();
  const hours = date.getHours();
  const minutes = date.getMinutes();
  const seconds = date.getSeconds();
  
  let result = format;
  result = result.replace('YYYY', year.toString());
  result = result.replace('MM', month.toString().padStart(2, '0'));
  result = result.replace('DD', day.toString().padStart(2, '0'));
  result = result.replace('HH', hours.toString().padStart(2, '0'));
  result = result.replace('mm', minutes.toString().padStart(2, '0'));
  result = result.replace('ss', seconds.toString().padStart(2, '0'));
  
  return result;
}

格式化示例

格式字符串 输出示例
'YYYY-MM-DD' 2024-01-15
'YYYY年MM月DD日' 2024年01月15日
'MM/DD/YYYY' 01/15/2024
'HH:mm:ss' 14:30:25

五、颜色格式转换

5.1 颜色基础知识

在UI开发中,颜色格式转换非常常见:

  • HEX :十六进制格式,如#FF5733
  • RGB :红绿蓝格式,如rgb(255, 87, 51)
  • HSL :色相饱和度亮度,如hsl(9, 100%, 60%)

5.2 HEX转RGB

typescript 复制代码
export function hexToRgb(hex: string): ConvertResult {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  if (!result) {
    return { success: false, value: '', error: '无效的十六进制颜色' };
  }
  const r = parseInt(result[1], 16);
  const g = parseInt(result[2], 16);
  const b = parseInt(result[3], 16);
  return { success: true, value: `rgb(${r}, ${g}, ${b})` };
}

正则表达式解析

复制代码
^#?           - 可选的#号
([a-f\d]{2})  - 第一组:两个十六进制字符
([a-f\d]{2})  - 第二组:两个十六进制字符
([a-f\d]{2})  - 第三组:两个十六进制字符
$/i           - 不区分大小写

5.3 RGB转HEX

typescript 复制代码
export function rgbToHex(rgb: string): ConvertResult {
  const result = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i.exec(rgb);
  if (!result) {
    return { success: false, value: '', error: '无效的RGB颜色格式' };
  }
  const r = parseInt(result[1]);
  const g = parseInt(result[2]);
  const b = parseInt(result[3]);
  
  if (r < 0 || r > 255 || g < 0 || g > 255 || b < 0 || b > 255) {
    return { success: false, value: '', error: 'RGB值必须在0-255之间' };
  }
  
  const hex = '#' + 
    r.toString(16).padStart(2, '0') + 
    g.toString(16).padStart(2, '0') + 
    b.toString(16).padStart(2, '0');
  
  return { success: true, value: hex.toUpperCase() };
}

5.4 HEX转HSL

HSL转换在颜色选择器等场景中非常有用:

typescript 复制代码
export function hexToHsl(hex: string): ConvertResult {
  const rgbResult = hexToRgb(hex);
  if (!rgbResult.success) {
    return rgbResult;
  }
  
  const rgbMatch = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/.exec(rgbResult.value);
  if (!rgbMatch) {
    return { success: false, value: '', error: '转换失败' };
  }
  
  let r = parseInt(rgbMatch[1]) / 255;
  let g = parseInt(rgbMatch[2]) / 255;
  let b = parseInt(rgbMatch[3]) / 255;
  
  const max = Math.max(r, g, b);
  const min = Math.min(r, g, b);
  let h = 0, s = 0;
  let l = (max + min) / 2;
  
  if (max !== min) {
    const d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    
    switch (max) {
      case r: h = ((g - b) / d + (g < b ? 6 : 0)) / 6; break;
      case g: h = ((b - r) / d + 2) / 6; break;
      case b: h = ((r - g) / d + 4) / 6; break;
    }
  }
  
  h = Math.round(h * 360);
  s = Math.round(s * 100);
  l = Math.round(l * 100);
  
  return { success: true, value: `hsl(${h}, ${s}%, ${l}%)` };
}

5.5 颜色转换在UI中的应用

typescript 复制代码
@Component
struct ColorPreview {
  @Prop colorValue: string;
  
  build() {
    Column({ space: 16 }) {
      Row() {
        Row()
          .width(80)
          .height(80)
          .backgroundColor(this.colorValue)
          .borderRadius(8)
        
        Row()
          .width(80)
          .height(80)
          .backgroundColor(this.colorValue)
          .borderRadius(8)
          .border({ width: 1, color: '#E0E0E0' })
        
        Row()
          .width(80)
          .height(80)
          .backgroundColor('#1C1C1E')
          .borderRadius(8)
      }
      
      Text(this.colorValue)
        .fontSize(14)
        .fontColor('#666666')
    }
  }
}

六、进制转换

6.1 二进制与字符串转换

typescript 复制代码
export function stringToBinary(str: string): ConvertResult {
  let result = '';
  
  for (let i = 0; i < str.length; i++) {
    const charCode = str.charCodeAt(i);
    const binary = charCode.toString(2).padStart(8, '0');
    result += binary + (i < str.length - 1 ? ' ' : '');
  }
  
  return { success: true, value: result };
}

export function binaryToString(binary: string): ConvertResult {
  const parts = binary.split(' ');
  let result = '';
  
  for (let i = 0; i < parts.length; i++) {
    const byte = parts[i].trim();
    if (!byte) continue;
    if (!/^[01]{8}$/.test(byte)) {
      return { success: false, value: '', error: '无效的二进制格式' };
    }
    const charCode = parseInt(byte, 2);
    result += String.fromCharCode(charCode);
  }
  
  return { success: true, value: result };
}

转换示例

typescript 复制代码
stringToBinary('Hello'); 
// 输出: 01001000 01100101 01101100 01101100 01101111

binaryToString('01001000 01100101');
// 输出: He

6.2 十进制与二进制转换

typescript 复制代码
export function decimalToBinary(decimal: string): ConvertResult {
  const num = parseInt(decimal);
  if (isNaN(num)) {
    return { success: false, value: '', error: '无效的十进制数' };
  }
  return { success: true, value: num.toString(2) };
}

export function binaryToDecimal(binary: string): ConvertResult {
  if (!/^[01]+$/.test(binary)) {
    return { success: false, value: '', error: '无效的二进制数' };
  }
  const num = parseInt(binary, 2);
  return { success: true, value: num.toString() };
}

6.3 十进制与十六进制转换

typescript 复制代码
export function decimalToHex(decimal: string): ConvertResult {
  const num = parseInt(decimal);
  if (isNaN(num)) {
    return { success: false, value: '', error: '无效的十进制数' };
  }
  return { success: true, value: '0x' + num.toString(16).toUpperCase() };
}

export function hexToDecimal(hex: string): ConvertResult {
  const cleanHex = hex.replace(/^0x/i, '');
  if (!/^[0-9a-f]+$/i.test(cleanHex)) {
    return { success: false, value: '', error: '无效的十六进制数' };
  }
  const num = parseInt(cleanHex, 16);
  return { success: true, value: num.toString() };
}

6.4 进制转换应用场景

typescript 复制代码
// 内存地址显示
function formatMemoryAddress(address: number): string {
  return '0x' + address.toString(16).toUpperCase().padStart(8, '0');
}

// 权限位掩码
const PERMISSION_READ = 0b001;
const PERMISSION_WRITE = 0b010;
const PERMISSION_EXECUTE = 0b100;

function hasPermission(mask: number, permission: number): boolean {
  return (mask & permission) === permission;
}

// 颜色值处理
function parseColorValue(hex: string): { r: number; g: number; b: number } {
  const clean = hex.replace('#', '');
  return {
    r: parseInt(clean.substring(0, 2), 16),
    g: parseInt(clean.substring(2, 4), 16),
    b: parseInt(clean.substring(4, 6), 16)
  };
}

七、JSON序列化与反序列化

7.1 JSON.parse与JSON.stringify

JSON转换在ArkTS中需要特别注意类型安全:

typescript 复制代码
export function stringToJson(value: string): ConvertResult {
  try {
    const parsed: object | string | number | boolean | null = 
      JSON.parse(value) as object | string | number | boolean | null;
    return { success: true, value: JSON.stringify(parsed, null, 2) };
  } catch {
    return { success: false, value: '', error: '无效的JSON格式' };
  }
}

关键点

  • 使用try-catch捕获解析异常
  • 显式指定JSON.parse的返回类型
  • 使用as进行类型断言

7.2 JSON与对象互转

typescript 复制代码
interface User {
  id: number;
  name: string;
  email: string;
}

function jsonToUser(json: string): User | null {
  try {
    const parsed = JSON.parse(json);
    if (typeof parsed === 'object' && parsed !== null) {
      const obj = parsed as Record<string, object | null>;
      if (typeof obj.id === 'number' && 
          typeof obj.name === 'string' && 
          typeof obj.email === 'string') {
        return {
          id: obj.id,
          name: obj.name,
          email: obj.email
        };
      }
    }
    return null;
  } catch {
    return null;
  }
}

function userToJson(user: User): string {
  return JSON.stringify(user);
}

7.3 大数字处理

JavaScript/ArkTS中的数字有精度限制,对于大数字需要特殊处理:

typescript 复制代码
function serializeBigNumber(num: bigint): string {
  return num.toString();
}

function parseBigNumber(str: string): bigint {
  return BigInt(str);
}

八、类型安全策略

8.1 类型守卫

类型守卫是确保类型安全的重要手段:

typescript 复制代码
function isString(value: object | null): value is string {
  return typeof value === 'string';
}

function isNumber(value: object | null): value is number {
  return typeof value === 'number';
}

function isValidUser(obj: object | null): obj is User {
  if (obj === null || typeof obj !== 'object') {
    return false;
  }
  const user = obj as Record<string, object | null>;
  return isNumber(user.id) && 
         isString(user.name) && 
         isString(user.email);
}

8.2 防御性编程

在类型转换中,防御性编程尤为重要:

typescript 复制代码
export function safeGetProperty<T>(
  obj: Record<string, T> | null,
  key: string,
  defaultValue: T
): T {
  if (obj === null || obj === undefined) {
    return defaultValue;
  }
  const value = obj[key];
  return value !== undefined ? value : defaultValue;
}

export function safeParseInt(value: string, defaultValue: number = 0): number {
  const parsed = parseInt(value);
  return isNaN(parsed) ? defaultValue : parsed;
}

export function safeParseFloat(value: string, defaultValue: number = 0): number {
  const parsed = parseFloat(value);
  return isNaN(parsed) ? defaultValue : parsed;
}

8.3 Result类型模式

借鉴函数式编程的Result类型:

typescript 复制代码
export type Result<T> = 
  | { success: true; value: T }
  | { success: false; error: string };

export function tryParseInt(value: string): Result<number> {
  const parsed = parseInt(value);
  if (isNaN(parsed)) {
    return { success: false, error: `无法将"${value}"转换为整数` };
  }
  return { success: true, value: parsed };
}

export function tryStringToDate(value: string): Result<Date> {
  const date = new Date(value);
  if (isNaN(date.getTime())) {
    return { success: false, error: `无效的日期格式: "${value}"` };
  }
  return { success: true, value: date };
}

8.4 显式类型声明

ArkTS要求显式的类型声明:

typescript 复制代码
// 避免隐式any
const result = someFunction(); // 可能报错

// 显式声明类型
const result: ConvertResult = someFunction();

// 泛型约束
function identity<T extends string | number>(value: T): T {
  return value;
}

九、性能优化策略

9.1 避免重复转换

对于频繁使用的转换结果,可以考虑缓存:

typescript 复制代码
class ConversionCache {
  private cache: Map<string, string> = new Map();
  
  get(key: string): string | undefined {
    return this.cache.get(key);
  }
  
  set(key: string, value: string): void {
    this.cache.set(key, value);
  }
  
  clear(): void {
    this.cache.clear();
  }
  
  compute(key: string, computeFn: () => string): string {
    const cached = this.cache.get(key);
    if (cached !== undefined) {
      return cached;
    }
    const result = computeFn();
    this.cache.set(key, result);
    return result;
  }
}

const colorCache = new ConversionCache();

function getRgbFromHex(hex: string): string {
  return colorCache.compute(`hex:${hex}`, () => {
    const result = hexToRgb(hex);
    return result.success ? result.value : '';
  });
}

9.2 批量转换优化

处理大量数据时,批量转换可以显著提升性能:

typescript 复制代码
function batchStringToNumber(inputs: string[]): number[] {
  const results: number[] = [];
  for (let i = 0; i < inputs.length; i++) {
    const num = parseFloat(inputs[i]);
    results.push(isNaN(num) ? 0 : num);
  }
  return results;
}

function batchHexToRgb(inputs: string[]): string[] {
  const results: string[] = [];
  for (let i = 0; i < inputs.length; i++) {
    const result = hexToRgb(inputs[i]);
    results.push(result.success ? result.value : '');
  }
  return results;
}

9.3 正则表达式编译优化

频繁使用的正则表达式应该提前编译:

typescript 复制代码
const HEX_COLOR_REGEX = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i;
const RGB_COLOR_REGEX = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/i;
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

export function hexToRgbOptimized(hex: string): ConvertResult {
  const result = HEX_COLOR_REGEX.exec(hex);
  if (!result) {
    return { success: false, value: '', error: '无效的十六进制颜色' };
  }
  const r = parseInt(result[1], 16);
  const g = parseInt(result[2], 16);
  const b = parseInt(result[3], 16);
  return { success: true, value: `rgb(${r}, ${g}, ${b})` };
}

9.4 惰性计算

对于不总是需要的结果,使用惰性计算:

typescript 复制代码
class LazyConverter {
  private sourceValue: string = '';
  private cachedResult: ConvertResult | null = null;
  private converter: (value: string) => ConvertResult;
  
  constructor(converter: (value: string) => ConvertResult) {
    this.converter = converter;
  }
  
  update(value: string): void {
    if (this.sourceValue !== value) {
      this.sourceValue = value;
      this.cachedResult = null;
    }
  }
  
  getResult(): ConvertResult {
    if (this.cachedResult === null) {
      this.cachedResult = this.converter(this.sourceValue);
    }
    return this.cachedResult;
  }
}

const lazyHexToRgb = new LazyConverter(hexToRgb);

十、实战案例:类型转换工具应用

10.1 应用架构

复制代码
├── common/
│   └── utils/
│       ├── converter.ets    # 类型转换函数
│       └── index.ets        # 导出入口
├── pages/
│   └── Index.ets            # 演示页面
└── entry/src/main/ets/

10.2 核心数据结构

typescript 复制代码
export interface ConvertOption {
  id: string;
  name: string;
  fromType: string;
  toType: string;
  placeholder: string;
  example: string;
  description: string;
}

export const convertOptions: ConvertOption[] = [
  {
    id: 'stringToNumber',
    name: '字符串转数字',
    fromType: '字符串',
    toType: '数字',
    placeholder: '请输入字符串',
    example: '123.45',
    description: '将字符串转换为数字'
  },
  // ... 更多转换选项
];

10.3 转换执行器

typescript 复制代码
class ConversionExecutor {
  execute(id: string, input: string): ConvertResult {
    switch (id) {
      case 'stringToNumber':
        return stringToNumber(input);
      case 'stringToBoolean':
        return stringToBoolean(input);
      case 'hexToRgb':
        return hexToRgb(input);
      case 'decimalToBinary':
        return decimalToBinary(input);
      // ... 更多转换类型
      default:
        return { success: false, value: '', error: '未知转换类型' };
    }
  }
}

十一、常见问题与解决方案

11.1 浮点数精度问题

typescript 复制代码
// 问题:0.1 + 0.2 !== 0.3
const sum = 0.1 + 0.2; // 0.30000000000000004

// 解决方案:使用整数运算或精确计算库
function preciseAdd(a: number, b: number, decimals: number = 2): number {
  const multiplier = Math.pow(10, decimals);
  return Math.round((a + b) * multiplier) / multiplier;
}

11.2 大数字精度问题

typescript 复制代码
// 问题:超过Number.MAX_SAFE_INTEGER的数字会丢失精度
const bigNum = 9007199254740993; // 可能不准确

// 解决方案:使用BigInt
const safeBigNum = BigInt('9007199254740993');

11.3 日期解析兼容性

typescript 复制代码
// 问题:不同浏览器对日期格式的解析可能不同
const date1 = new Date('2024-01-15'); // 可能有时区问题
const date2 = new Date('01/15/2024'); // 部分浏览器不支持

// 解决方案:使用ISO 8601格式或手动解析
function parseDateSafe(dateStr: string): Date | null {
  const parts = dateStr.split(/[-\/]/);
  if (parts.length !== 3) return null;
  
  const year = parseInt(parts[0]);
  const month = parseInt(parts[1]) - 1;
  const day = parseInt(parts[2]);
  
  if (isNaN(year) || isNaN(month) || isNaN(day)) return null;
  
  return new Date(year, month, day);
}

11.4 Unicode编码问题

typescript 复制代码
// 问题:表情符号等代理对可能影响字符串长度
const emoji = '😀';
emoji.length; // 2(代理对)

// 解决方案:使用Array.from或展开运算符
const emojiLength = [...emoji].length; // 1

十二、测试策略

12.1 单元测试

typescript 复制代码
describe('Converter Tests', () => {
  it('stringToNumber should parse valid numbers', () => {
    expect(stringToNumber('123').success).toBe(true);
    expect(stringToNumber('3.14').success).toBe(true);
    expect(stringToNumber('abc').success).toBe(false);
  });
  
  it('hexToRgb should convert colors correctly', () => {
    const result = hexToRgb('#FF5733');
    expect(result.success).toBe(true);
    expect(result.value).toBe('rgb(255, 87, 51)');
  });
  
  it('decimalToBinary should convert correctly', () => {
    expect(decimalToBinary('42').value).toBe('101010');
    expect(decimalToBinary('255').value).toBe('11111111');
  });
});

12.2 边界测试

typescript 复制代码
it('should handle edge cases', () => {
  // 空字符串
  expect(stringToNumber('').success).toBe(false);
  
  // 负数
  expect(stringToNumber('-123').success).toBe(true);
  
  // 科学计数法
  expect(stringToNumber('1e5').success).toBe(true);
  
  // 数字开头
  expect(stringToNumber('123abc').success).toBe(true); // parseFloat会截断
});

总结

本文深入分析了HarmonyOS ArkTS中的类型转换机制,涵盖了从基础类型转换到高级应用的各个方面:

  1. 字符串与数字转换 :使用parseIntparseFloat,配合isNaN检查
  2. 字符串与布尔转换:需要显式实现转换逻辑
  3. 日期时间转换 :利用Date对象的各种方法
  4. 颜色格式转换:HEX、RGB、HSL之间的互转
  5. 进制转换:二进制、十进制、十六进制互转
  6. JSON序列化:处理parse和stringify
  7. 类型安全:类型守卫、防御性编程、Result类型
  8. 性能优化:缓存、批量处理、正则预编译

在实际开发中,应该:

  • 优先使用类型安全的转换方式
  • 对所有转换结果进行验证
  • 使用统一的错误处理机制
  • 根据场景选择合适的性能优化策略
  • 编写完善的测试用例

通过本文的学习,开发者应该能够掌握ArkTS中类型转换的核心技术,在实际项目中编写出高质量的类型转换代码。


附录:转换函数速查表

转换类型 函数 输入示例 输出示例
字符串→数字 stringToNumber '123.45' '123.45'
字符串→布尔 stringToBoolean 'true' 'true'
字符串→日期 stringToDate '2024-01-15' '2024-01-15 00:00:00'
HEX→RGB hexToRgb '#FF5733' 'rgb(255, 87, 51)'
RGB→HEX rgbToHex 'rgb(255,87,51)' '#FF5733'
字符串→二进制 stringToBinary 'Hi' '01001000 01101001'
十进制→二进制 decimalToBinary '42' '101010'
十进制→十六进制 decimalToHex '255' '0xFF'
相关推荐
vortex51 小时前
苏格拉底学习法:通过提问驱动的深度思考
学习
金启攻1 小时前
鸿蒙原生应用实战(四):我的追剧与统计页 —— 三态Tab与数据可视化
华为·harmonyos
爱喝水的鱼丶1 小时前
SAP-ABAP:SAP多表连接视图实战:内连接/外连接配置逻辑与性能优化技巧
运维·开发语言·学习·性能优化·sap·abap
星恒随风1 小时前
C++ 类和对象入门(六):友元、内部类、匿名对象和编译器优化
开发语言·c++·笔记·学习·状态模式
结城明日奈是我老婆1 小时前
stm32的TIM和PWM学习笔记
笔记·stm32·学习
AI_零食1 小时前
HarmonyOS ArkTS 数据格式化技术深度解析
学习·华为·harmonyos·鸿蒙
暗夜猎手-大魔王1 小时前
hermes源码学习7--会话存储
人工智能·学习
Dovis(誓平步青云)1 小时前
《QT学习第五篇:QSS美化界面与API绘图》
开发语言·数据库·qt·学习·时序数据库·开源智能体