有没有类似于 C/C#
的方法呢?
比如(C# 风格)
for (int i = 0; i < 100; i++)
{
if (i == 66)
break;
}
有没有类似于 C/C#
的方法呢?
比如(C# 风格)
for (int i = 0; i < 100; i++)
{
if (i == 66)
break;
}
简短回答是不需要。你通常可以使用一些高阶函数来表达相同的功能。有许多函数可供使用,对应着不同的模式(因此如果您描述清楚您需要什么,有人可能会给您更好的答案)。
例如,tryFind
函数从序列中返回第一个使给定谓词返回true
的值,这样您就可以编写类似以下的代码:
seq { 0 .. 100 } |> Seq.tryFind (fun i ->
printfn "%d" i
i=66)
实际上,如果您正在表达一些高级逻辑并且有相应的函数,则这是最好的方法。如果确实需要表达类似于break
的内容,则可以使用递归函数:
let rec loop n =
if n < 66 then
printfn "%d" n
loop (n + 1)
loop 0
更加神秘的选项(效率不如其他方法,但适用于DSL)是您可以定义一个计算表达式,让您编写 break
和continue
。这里是一个例子,但正如我所说,这并不高效。
这真的很丑,但在我的情况下它起作用了。
let mutable Break = false
while not Break do
//doStuff
if breakCondition then
Break <- true
done
这对于 do-while 循环很有用,因为它保证了循环至少执行一次。
我希望有一个更优雅的解决方案。我不喜欢递归的方法,因为我担心堆栈溢出。 :-(
let (i, ans) = (ref 0, ref -1)
while(!i < 100 and !ans < 0) do
if !i = 66 then
ans := !i
ans
(当i到达66时,代码出现错误——但是语法确实有很大不同,引入了另一个变量等等。)
i
,所以这需要很长的时间。 :-) - Edward Brey:=
运算符是什么? - knocteseq {
for i = 0 to 99 do
if i = 66 then yield ()
}
|> Seq.tryItem 0
|> ignore
试试这个:
exception BreakException
try
for i = 0 to 99 do
if i = 66 then
raise BreakException
with BreakException -> ()
我知道有些人不喜欢使用异常。但它确实有其优点。
您无需考虑复杂的递归函数。当然,您可以这样做,但有时会让事情变得更加麻烦,而使用异常则更简单。
此方法允许您在循环体的一半中断执行。 (使用“break”标志方法也很简单,但它只允许在循环体的末尾中断执行。)
您可以轻松地从嵌套循环中退出。
let rec IfEqualsNumber start finish num =
if start = finish then false
elif
start = num then true
else
let start2 = start + 1
IfEqualsNumber start2 finish num
最近我尝试解决了一个类似的情况:
有一个包含10个数据的列表。每个数据都必须通过Restful服务器进行查询,然后获取结果。
let lst = [4;6;1;8]
List.map()
lst |> List.map (fun x ->
try
use sqlComd = ...
sqlComd.Parameters.Add("@Id", SqlDbType.BigInt).Value <- x
sqlComd.ExecuteScala() |> Some
with
| :? System.Data.SqlClient.SqlException as ex -> None
)
但是,正如所说的那样,这并不是最优解。当发生失败的API时,剩余的项目仍然会被处理。它们做了一些在最后被忽略的事情。
List.tryFindIndex()
与map()
不同,我们必须在lambda函数中将结果存储在某个地方。一个合理的选择是使用mutable
列表。因此,当tryFindIndex()
返回None
时,我们知道一切都很好,并且可以开始利用mutable
列表。
val myList: List<string>
let res = lst |> List.tryFindIndex (fun x ->
try
use sqlComd = ...
sqlComd.Parameters.Add("@Id", SqlDbType.BigInt).Value <- x
myList.Add(sqlComd.ExecuteScala())
false
with
|:? System.Data.SqlClient.SqlException as ex -> true
)
match res with
| Some _ -> printfn "Something went wrong"
| None -> printfn "Here is the 10 results..."
这种方法并不是很惯用,因为它使用异常来停止操作。
exception MyException of string
let makeCall lstLocal =
match lstLocal with
| [] -> []
| head::tail ->
try
use sqlComd = ...
sqlComd.Parameters.Add("@Id", SqlDbType.BigInt).Value <- x
let temp = sqlComd.ExecuteScala()
temp :: makeCall (tail)
with
|:? System.Data.SqlClient.SqlException as ex -> raise MyException ex.Message
try
let res = makeCall lst
printfn "Here is the 10 results..."
with
| :? MyException -> printfn "Something went wrong"
while... do
这仍然涉及到可变
列表。