我似乎无法理解这两种情况的规则:
1.结束索引可能比起始索引小1,产生一个空数组/字符串
2.将起始索引放在最后一个元素后面显然是合法的,如果结束索引少一个,就像以前一样。
[|0..2|].[3..2];; // [||]
"bar".[3..2];; // ""
在考虑案例1的情况下,对绑定检查的简单实现不允许使用案例2:
let trySlice i j (a : string) =
let lastIdx = a.Length - 1
if i < 0 || i > lastIdx || j < i - 1 || j > lastIdx then None
else Some a.[i..j]
trySlice 3 2 "bar" // None
这种行为背后的理由是什么?怎么办?
修改 这就是我现在感谢Tarmil的输入
let trySlice i j (a : string) =
if i >= 0 && j >= i - 1 && j < a.Length then Some a.[i..j]
else None
应该等同于
let trySlice' i j (s : string) =
try s.Substring(i, j - i + 1) |> Some
with _ -> None
答案 0 :(得分:1)
我认为基本原理是a.[i..j]
是一个长度为(j - i + 1)
的序列,因此在某种程度上允许i = j + 1
作为提取空序列的方法是有意义的。
至于“如何继续”,如果您希望trySlice
接受内置切片接受的所有情况,则只需删除i > lastIdx
子句。在i = lastIdx + 1
时,其他条件通过的唯一方法是j = lastIdx
,而i > lastIdx + 1
时,j
无法通过其约束。
作为旁注,你的写作方式:
if (failCondition || failCondition || ...) then None else Some x
由于某些原因,我感觉反直觉,我会把它写成:
if (successCondition && successCondition && ...) then Some x else None