在客户端开发中,你是否曾遇到过这样的困扰:一次看似寻常的网络数据解析,却导致了出人意料的崩溃;一个本该正常的文件读取操作,却返回了难以理解的数据错误。这些问题的根源,往往指向同一环节——数据类型转换。当应用面对网络传输、文件I/O等不可控的数据源时,如何稳健、准确地进行数据解析与转换,就成为保障应用稳定性的第一道防线。

本篇内容是《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》这本书第四章内容的延续,是咱这本书读者的福利,在本篇内容中以模拟多种数据输入,向基础数据类型转换的输出,以确定最优的代码编方式,以避免非预期的异常产生,每个示例可以独立的编译及调试,欢迎大家一同来深入的解,甚至可以当作面试题来学习。

打个广告,对本书感兴趣的同学可以点击以下链接进行购买,或者了解我的班级参加 班级共同学习,点击链接可进入(华为官方活动)

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_字符串

往期福利:

  1. 【页面路由导航】三步实现页面跳转的完整示例-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利
  2. 【鸿蒙生态共建】一文10个示例讲懂鸿蒙系统ArkTS中的null与undefined的区别与应用-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利
  3. 【鸿蒙生态共建】一文两表三实例讲清async函数与普通函数的区别-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利

1: 基础测试数据准备

在ArkTS中,由于语言的特性,无法直接对 null 及 undefined 进行直接强转,故先将该数据存到Record中,之后再使用,由于在Record类型数据中指定的key没有value时会返回undefined,故在示例中没有添加该value为undefined的数据项。

// 声明一个变量testRecord,其中包含字串、数字和null数据,可以通过testRecord获取对应的不同类型数据
const testRecord:Record<string,Object|null|number>= {"null_key":null,"str_key":"1xxx","num_key":"666"}

2: 不同类型数据转string

下面的示例中,分别将null、undefined、通过Strinrg(...) 和 ... as string进行向字符串转换。

const String_null = String(null)
// String(null) null
console.log("俩毛豆 String(null) " + String_null)

const String_undefined = String(undefined)
// String(undefined) undefined
console.log("俩毛豆 String(undefined) " + String_undefined)

const testRecord_null = testRecord["null_key"];
const nullAsString = testRecord_null as String;
// nullValueAsString null
console.log("俩毛豆 nullValueAsString " + nullAsString)

const testRecord_nokey = testRecord["nokey"];
const noKeyValueAsString = testRecord_nokey as String;

// noKeyValueAsString undefined
console.log("俩毛豆 noKeyValueAsString " + noKeyValueAsString)

对应的log输出及编译调试时的变量状态的截图,因为log输出是没有双引号的,需要注意一下实际的变量值,可以看出,String(...)操作在强转时会把null和undefined强转为"null"和"undefined"。而... as string的操作对于null和undefined强转之后的结果依然是null和undefined。这时如果判断字符串是否有效,使用的方式就有所不同了。或者应该先对该原值进行有效性判断之后,再进行字符串的转换。

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_字符串_02

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_App_03

3: 不同类型转number

下面的示例中,分别将null、undefined及非纯字符的字串、通过Number(...) 和 ... as number进行转换。

const Number_null = Number(null)
// Number(null) 0
console.log("俩毛豆 Number(null) " + Number_null)
const Number_undefined = Number(undefined)
// Number(undefined) NaN
console.log("俩毛豆 Number(undefined) " + Number_undefined)

const nullAsNumber = testRecord_null as number;
// nullAsNumber null
console.log("俩毛豆 nullAsNumber " + nullAsNumber)
const noKeyValueAsNumber = testRecord_nokey as number;
// noKeyValueAsNumber undefined
console.log("俩毛豆 noKeyValueAsNumber " + noKeyValueAsNumber)

// 特定场景,非数字字串转数字
const Number_str = Number("1xxx");
// Number_str NaN
console.log("俩毛豆 Number_str " + Number_str)
const strValueAsNumber = testRecord["str_key"]  as number;
// strValueAsNumber 1xxx
console.log("俩毛豆 strValueAsNumber " + strValueAsNumber)
// Number_str type number
console.log("俩毛豆 Number_str type " + typeof Number_str)

对应的log输出及编译调试时的变量状态的截图,可以看出,Number(...)操作在强转时会把null和undefined强转为0和NaN。而... as number的操作对于null和undefined强转之后的结果依然是null和undefined。当输入的数据为非纯数字的字符串时,Number(...)操作在强转时会把非纯数字的字符串强转为NaN,而... as number的操作对于非纯数字的字符串强转之后的结果依然是原字串。这时如果判断数字是否有效,使用的方式也是需要分别对待。个人建议应该先对该原值进行有效性判断之后,再进行数值的转换,再进行一次数值的有效性判断。注意,NaN的类型是number

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_App_04

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_App_05


4: NaN类型的判断

在前面的内容中有部分内容转换为NaN,关于null及undefined的判断方式是较基础的知识,在这里就不作过多的介绍,NaN的判断有些特殊,下面的代码分别使用多种判断方式,进行对比。

// Number_str == Number.NaN false
if (Number.NaN == Number.NaN) {
  console.log("俩毛豆 Number.NaN == Number.NaN true");
} else {
  console.log("俩毛豆 Number.NaN == Number.NaN false");
}

// Number.NaN !== Number.NaN true
if (Number.NaN !== Number.NaN) {
  console.log("俩毛豆 Number.NaN !== Number.NaN true");
} else {
  console.log("俩毛豆 Number.NaN !== Number.NaN false");
}
// Number.NaN != Number.NaN true
if (Number.NaN != Number.NaN) {
  console.log("俩毛豆 Number.NaN != Number.NaN true");
} else {
  console.log("俩毛豆 Number.NaN != Number.NaN false");
}

// Number.isNaN(num) true
if (Number.isNaN(Number_str)) {
  console.log("俩毛豆 Number.isNaN(num) true");
} else {
  console.log("俩毛豆 Number.isNaN(num) false");
}

对应的log输出的截图,在ArkTS中,Number.NaN是Number类型的一个特殊值。它被用来表示非数值,这里的数值是指在IEEE浮点数算术标准中定义的双精度64位格式的值。在ArkTS中,Number.NaN的独特之处在于它不等于任何值,包括其本身。与Number.NaN进行比较时,结果是令人困惑的:Number.NaN !== Number.NaN 和 Number.NaN != Number.NaN 的值都是 true。因此,必须使用Number.isNaN()函数来测试一个值是否是Number.NaN。

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_数据_06


总结: 

在本篇的内容中,介绍了非预期(异常)数据转string和number的情况,目标是了解不同数据在转换时的实际结果,在客户端编码时提前作好预防,避免因外因导致的异常产生。

下图为转换之前的数据项及转换之后的数据项的实际内存值,可以看出Number(...)及String(..)的转换处理逻辑要强一些(会改变原始类型和值),而 ...as number及...as string的转换的处理逻辑要弱一些(不会改变原始类型及值),在实际研发过程中,需要进行必要的有效性验证,以保证应用运行的稳定性,特别是外部输入的数据,有效性验证是必需要作的工作。

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_harmonyOS_07


最后再打下广告,对本书感兴趣的同学可以点击以下链接进行购买,或者了解我的班级参加 班级共同学习,点击链接可进入(华为官方活动)

【鸿蒙生态共建】一文说清基础类型数据的非预期输入转换与兜底-《精通HarmonyOS NEXT :鸿蒙App开发入门与项目化实战》读者福利_字符串_08