F#在复杂语句中中断while循环

F#在复杂语句中中断while循环,f#,F#,我有这样一个功能: let ScanColors() = for i in 1..54 do let mutable c = Unchecked.defaultof<string> if (i = 9) then c <- "U - WHITE" else if (i <> 0 && i%9 = 0) then

我有这样一个功能:

let ScanColors() =
    for i in 1..54 do
        let mutable c = Unchecked.defaultof<string>

        if (i = 9) then 
            c <- "U - WHITE"
        else
            if (i <> 0 && i%9 = 0) then 
                MoveSensor(SensorPos.THIRD)
            else
                MoveSensor(
                    match ((i - (i/9)*9)%2 <> 0) with 
                        | true -> SensorPos.SECOND
                        | false -> SensorPos.FIRST)

            while (true) do
                c <- ScanColor()
                if (c = "ERR") then
                    CalibrateSensorPosition()
                else
                   break
            ResetSensorPosition()
let ScanColors()=
因为我在1..54做
设可变c=Unchecked.defaultof
如果(i=9),则
c传感器位置秒
|错误->传感器位置第一)
虽然(真的)是这样
c遗憾的是F#不支持
break
。有各种相当复杂的方法来处理这个问题(比如或我的),但这些方法都有缺点,使代码相当复杂

处理此问题的一般方法是使用递归重写代码-这通常会编译成与使用
break
continue
在C中编写的相同的IL

因此,代码段中的
while
块可以编写为一个递归调用自身的函数,直到结果不是“ERR”,然后返回
c

let rec scanWhileErr () =     
  let c = ScanColor()
  if c = "ERR" then
    CalibrateSensorPosition()
    scanWhileErr()
  else c
然后从主块调用此函数:

if (i <> 0 && i%9 = 0) then 
  MoveSensor(SensorPos.THIRD)
else
  MoveSensor(if (i - (i/9)*9)%2 <> 0 then SensorPos.SECOND else SensorPos.FIRST)

c <- scanWhileErr ()
ResetSensorPosition()
如果(i 0&&i%9=0)那么
移动传感器(传感器位置3)
其他的
移动传感器(如果(i-(i/9)*9)%2 0则传感器位置第二,否则传感器位置第一)
c中断在F#中不存在,就个人而言,即使在c#中,我也会尽量避免中断,因为有许多替代/更干净的方法来中断循环

在保持命令式代码风格的同时,一个简单的修复方法是:

c <- ScanColor()
while (c = "ERR") do
    CalibrateSensorPosition()
    c <- ScanColor()
ResetSensorPosition()

c事实上,我认为这种方法很好,在我的情况下是有效的:

        let mutable flag = true
        while (flag = true) do
            c <- ScanColor()
            if (c = "ERR") then
                CalibrateSensorPosition()
            else
               flag <- false
        ResetSensorPosition()
let mutable flag=true
而(flag=true)do

c我认为一个简单的方法是,当循环中需要“中断”时,您只需确保循环终止

这方面的一个例子是,如果我们有一个类似这样的while循环

while i < upperlimit do
   if a
   then break
而我<上限do
如果
然后打破

Tomas,我的功能顺序很重要。例如,我必须首先使用if-else中的函数,然后编写while循环。您的解决方案是完美的,但如果我实现了这一点,我的事件顺序将发生变化。例如,在调用CalibrateSensorPosition()之前,我必须调用MoveSensor()函数。我们如何根据顺序实现该方法?您可以将其定义为本地函数,并从主函数的正确位置调用它。我相信我的代码片段保留了您的调用顺序……是的,使用(可变)标志也可以完成这项工作。但是在while条件中不需要
=true
,它是冗余的。你可以写“<代码>,而标志做< /代码>不投票,但我不认为变异性“罚款”,当其他,更惯用,选项是可用的,也一样容易。我不会让它通过工作中的代码审查我同意@ildjarn,但如果它是C代码或其他语言的翻译,我会立即接受它。一旦翻译完成并经过充分的测试和接受,我会考虑重构到更多的F -Y-ISH风格,去除不必要的变化。我认为这更清楚地描绘了代码的意图。本地化并包含时,可变性是正常的。
while i < upperlimit do
   if a
   then break