> let a = [| 'a'..'d' |];;
val a : char [] = [|'a'; 'b'; 'c'; 'd'|]
做琐碎的切片:
> a.[1..2], [1..2];;
val it : char [] * int list = ([|'b'; 'c'|], [1; 2])
现在尝试使用空白区域:
> a.[1..0], [1..0];;
val it : char [] * int list = ([||], [])
似乎工作合理 - 我们有两个空序列。
但它在这里失败了:
> a.[5..0];;
System.OverflowException: Arithmetic operation resulted in an overflow.
at <StartupCode$FSI_0018>.$FSI_0018.main@()
Stopped due to error
当然,有一种解决方法[| for i in [5..0] -> a.[i] |]
。但我想念a.[5..0]
失败的原因?为什么不直接返回空数组?出现这种行为的原因是什么?
答案 0 :(得分:5)
这是一个错误。
虽然数组切片和范围表达式是不同的概念(例如,您不能使用a.[1..2..5]
),但它们应该表现一致。
请注意,当a.[start..finish]
(finish - start <= -2
失败时)a.[3..1]
发生异常,如果finish - start = -1
(a.[5..4] = [||]
)数组切片工作正常。
使用GetArraySlice中的prim-types.fs函数完成数组切片:
let inline GetArraySlice (arr: _[]) start finish =
let start = (match start with None -> 0 | Some n -> n)
let finish = (match finish with None -> arr.Length - 1 | Some n -> n)
GetArraySub arr start (finish - start + 1)
虽然GetArraySub
在同一模块中实现如下:
let inline GetArraySub arr (start:int) (len:int) =
let dst = zeroCreate len
for i = 0 to len - 1 do
SetArray dst i (GetArray arr (start + i))
dst
如果finish - start = -1
,我们在len = 0
中有GetArraySub
而zeroCreate 0
会返回一个空数组。 finish - start <= -2
导致len < 0
和zeroCreate len
失败的情况不再如此。
这可以通过在finish - start <= -1
时始终返回空数组来解决。