2012-04-22 2 views
6
> 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>[email protected]() 
Stopped due to error 

Конечно, есть обходной путь [| for i in [5..0] -> a.[i] |]. Но я скучаю по тому, почему a.[5..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.

+0

Вы знаете, где «официальный» трекер ошибок для F #? – qehgt

+1

Вы можете отправить отчет об ошибке в fsbugs (at) microsoft (dot) com. – pad

Смежные вопросы