在F#中尝试finally语句

Dan*_*all 1 f#

我是新手学习F#并编写一个简单的控制台应用程序,用户输入一个距离值,我想要一些验证来确保输入是一个数字.它还需要确保它是一个数字,如果不是,请告诉用户并重新开始.这是我到目前为止:

        let distance = 0

        while distance = 0 do 
            System.Console.WriteLine("How far do you want to travel?")
            let answer = System.Console.ReadLine()

            try
                let distance = System.Int32.Parse(answer)

                if distance < 0 then
                    let distance = 0
                    printfn "Can't use negative numbers"
                elif distance = 0 then
                    printfn "Can't travel a distance of 0"
                else
                    printfn "You are about to travel %A" distance

            finally
                let distance = 0
                printfn "Invalid distance format"
Run Code Online (Sandbox Code Playgroud)

这就是出现的问题:

![控制台应用程序的结果

在这个例子中,我想要发生的是"无效距离格式" 不会出现,它会移动到应用程序的下一部分.

我如何才能使"无效距离格式"仅在distance无法转换为int via时出现System.Int32.Parse(answer)

即使try-finally是完全错误的方式去做这件事,它还会怎么做呢?

提前致谢

kem*_*002 7

你想要的是什么 try...with

   try
      let distance = System.Int32.Parse(answer)
      . . . . .

   with
   | _ as ex -> printfn "Invalid Distance Format"
Run Code Online (Sandbox Code Playgroud)

http://fsharpforfunandprofit.com/posts/exceptions/

你也可以这样做

...
let attemptedConvert =  Int32.TryParse(answer)
let success,convertValue = attemptedConvert
if success then 
  //other stuff here
else 
  printfn "Invalid Number Format"
Run Code Online (Sandbox Code Playgroud)

这样就不会抛出任何异常,如果条目成功转换,您仍然可以进行验证.

如下所述,异常可能是比其他替代方案更昂贵的操作,应进行评估以查看是否会导致不必要的开销.与任何流程一样,这应该根据具体情况进行评估.

TryParse方法

  • 您应该注意,使用带有F#的异常是非常昂贵的,当一个人在使用异常或其他东西之间做出选择时,应该强烈考虑非异常版本. (4认同)
  • @GuyCoder我完全同意这种观点,但我认为明确的意图是表现的更好的理由.给定两个函数`parseInt:string - > int`和`tryParseInt:string - > int option`,类型系统会告诉您编写代码时第二个函数可能会失败,并且您需要处理可能的失败案例.第一个函数可能在运行时失败而没有警告.例外是处理预期失败的极其糟糕的方法. (3认同)