2012-04-22 50 views
6
> let a = [| 'a'..'d' |];; 
val a : char [] = [|'a'; 'b'; 'c'; 'd'|] 

Do cắt tầm thường:hành vi kỳ lạ của mảng slicing

> a.[1..2], [1..2];; 
val it : char [] * int list = ([|'b'; 'c'|], [1; 2]) 

Bây giờ thử nó với khu vực trống:

> a.[1..0], [1..0];; 
val it : char [] * int list = ([||], []) 

vẻ làm việc và hợp lý - chúng tôi có hai chuỗi rỗng.

Nhưng nó không thành công ở đây:

> a.[5..0];; 
System.OverflowException: Arithmetic operation resulted in an overflow. 
    at <StartupCode$FSI_0018>[email protected]() 
Stopped due to error 

Tất nhiên, có một cách giải quyết [| for i in [5..0] -> a.[i] |]. Nhưng tôi bỏ lỡ lý do tại sao a.[5..0] không thành công? Tại sao không chỉ trả về mảng trống? Bất kỳ lý do nào cho hành vi đó?

Trả lời

5

Đây là lỗi.

Mặc dù mảng cắt và phạm vi biểu thức là các khái niệm khác nhau (bạn không thể sử dụng a.[1..2..5] chẳng hạn), chúng phải hoạt động nhất quán.

Chú ý rằng ngoại lệ xảy ra với a.[start..finish] khi finish - start <= -2 (a.[3..1] thất bại) và mảng cắt hoạt động tốt nếu finish - start = -1 (a.[5..4] = [||]).

Mảng cắt được thực hiện bằng cách sử dụng GetArraySlice chức năng trong 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) 

khi GetArraySub được thực hiện trong các module tương tự như sau:

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 

Nếu finish - start = -1, chúng tôi có len = 0 trong GetArraySubzeroCreate 0 trả về một mảng trống. Nó không còn là trường hợp với finish - start <= -2 dẫn đến len < 0zeroCreate len không thành công.

Điều này có thể được khắc phục bằng cách luôn trả về một mảng trống bất cứ khi nào finish - start <= -1.

+0

Bạn có biết trình theo dõi lỗi "chính thức" cho F # không? – qehgt

+1

Bạn có thể gửi báo cáo lỗi tới fsbugs (at) microsoft (dot) com. – pad