理解严格模式警告

理解严格模式警告

> LeekScript 教程

你决定切换到严格模式,结果编辑器向你抛出了一大堆以前不存在的警告。别慌,严格模式的意义正是在于它不那么宽松,尤其是在类型方面给的自由更少。 让我们看几种常见的警告,先弄清楚它们指出的问题是什么,再找到解决办法。

从「real」类型到「integer」类型的危险转换

第一个简单的例子:我想把一个计算结果存进一个整数类型的变量。

这里的问题在于,函数 sqrt 总是返回一个实数类型的值,即使从数学上讲 sqrt(4) 等于 2。而一个实数无法无损地放进一个整数类型的变量:比如 sqrt(2) 的小数部分该怎么办?因此编译器要求你做出明确的选择。 解决这个警告有几种不同的办法:

从「integer?」类型到「integer」类型的危险转换

另一个例子:我有一个如下定义的整数关联数组(Map),我想把这个关联数组中的一个值同样存进一个整数类型的变量,按理说类型应该是一致的……

为什么警告说 mapEntier[0] 的类型是「integer?」而不是简单的「integer」? 提醒一下,类型末尾的「?」表示该类型也接受 null 值,相当于「integer | null」。那么,既然按照类型我的关联数组只包含 integer,它为什么可能返回一个 null 值呢?要读取关联数组中的一个值,需要给它传一个键,这里是方括号中的「0」,这个键必须是关联数组中定义的类型,这里是 integer,所以到这一步都没问题。但是没有任何东西能向编辑器保证这个键在关联数组中存在,而如果用一个不存在的键读取关联数组,返回值永远是 null。因此,通过键访问关联数组的返回值总是可空的。 现在来看看怎样解决这个问题,以消除警告:

从「(Array, Function any>)」类型到「()」类型的危险转换

这个例子中,我有一个想要排序的整数列表,按理说没什么复杂的,我甚至直接照搬了文档里的例子

可这简单的一行却给了我 2 个警告,先从第一个开始:它被括号包围,这意味着问题出在函数的参数上,参数不符合预期的签名。 让我们看看 arraySort 的文档中的签名:Function real | integer> => Array> 所以这是一个需要 2 个参数的函数,第一个参数是一个列表,第二个参数是一个同样接受 2 个参数并返回整数或实数的函数。第一个参数我们确实传了一个列表,这里没有问题,所以问题出在第二个参数上:我们传入的函数签名是 Function any>,而 arraySort 期望的是 Function real | integer>,返回类型不是所期望的。

回调函数的类型问题解决了,现在还剩第二个警告要处理。正如刚才所见,函数 arraySort 的返回值并不是我们的变量所期望的 Array\,而只是 Array,因此必须显式地转换返回值来修正这个问题。