F# 异常处理:如何解析 ReadLine() 中的数字?
F# Exception handling: how to parse number in ReadLine()?
我正在尝试从命令行输入中获取输入数字:
let mutable guess = Console.ReadLine() |> System.Int32.Parse
只要输入的是数字,这就可以正常工作;除非输入是字母字符串,例如 kdf
,程序将以 System.TypeInitilizationException
退出。
如何处理控制台输入中的字符串?
更新
我正在尝试用 F# 编写猜谜游戏。这是整个程序:
open System
printfn "Guess the number"
let secretNum = System.Random().Next(1,101)
let mutable continueLooping = true
while continueLooping do
printfn "Please input your guess."
let mutable input = Console.ReadLine()
let result =
match Int32.TryParse input with
| (true, result) -> Some(result)
| (false, _) -> printfn "Please input a number!"; None
let guess = Option.get result
printfn "You guessed: %A" guess
if guess < secretNum then printfn "Too small!"
else if guess > secretNum then printfn "Too big!"
else do
printfn "You win!"
continueLooping <- false
[<EntryPoint>]
let main argv =
printfn "%A" argv
0 // return an integer exit code
除了无法处理无效输入问题外,该程序的工作正常。我是编程新手,也许这对 .NET 程序员来说是一个很明显的问题。恐怕初学者经常有愚蠢的问题。
你看过Int32.TryParse了吗?
let parsed, guess = Console.ReadLine() |> System.Int32.TryParse
if parsed then ... else ...
我经常
match System.Int32.TryParse input with
| (true, number) -> ...
| (false, _) -> ....
对于 .net 中的所有 TryXY
模式也很有魅力 ;)
例子
F# Interactive for F# 3.1 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> let tryInt input = match System.Int32.TryParse input with | (true, number) -> Some number | _ -> None;;
val tryInt : input:string -> int option
> tryInt "55";;
val it : int option = Some 55
> tryInt "no";;
val it : int option = None
>
备注
我的猜测是您想查询您的用户,直到他输入一个有效的整数。所以你可以使用我刚刚给你的函数来用一个递归的类循环函数来做到这一点:
let rec queryAnInt () =
printf "please input an integer "
let input = System.Console.ReadLine()
match System.Int32.TryParse input with
| (true, number) -> number
| _ -> printfn "sorry - you did not enter an integer"
queryAnInt ()
现在 queryAnInt ()
会要求用户输入一个整数,直到他给了一个,return 就这样(没有 Option
你似乎有问题)
你的程序
以下是我在您的程序中看到的一些内容:
首先是显而易见的事情:当你真的想在 main
方法和功能 - 这会让你很快陷入困境
你将猜测匹配到 result
作为 Option
只是为了在下一行 Option.get result
中抛出所有你获得的东西,当result
是 None
(当用户没有输入数字时)- 这 是你真正的问题
你使用了一个全局可变变量和一个命令式循环——两者都是功能代码的味道
一个简单的重写(没有丑陋的可变)看起来像这样:
open System
let rec queryGuess () =
printf "please input your guess "
let input = Console.ReadLine()
match System.Int32.TryParse input with
| (true, number) when number >= 1 && number <= 100
-> number
| _ -> printfn "sorry - please enter a number between 1 and 100"
queryGuess ()
let rec guess secret nrTriesLeft =
if nrTriesLeft = 0 then printfn "Sorry you lost" else
match queryGuess () with
| g when g < secret ->
printfn "Too small!"
guess secret (nrTriesLeft - 1)
| g when g > secret ->
printfn "Too big!"
guess secret (nrTriesLeft - 1)
| g when g = secret ->
printfn "You win!"
| _ -> failwith "impossible case"
let game () =
printfn "Guess my secret number - it's between 1 and 100"
let secretNum = System.Random().Next(1,101)
guess secretNum 7 // 7 tries should always be enough - bonus question: why?
[<EntryPoint>]
let main _ =
game ()
0
这样你就可以很容易地扩展到让我们也只说一定数量的重试(只需稍微改变 guess
函数 - 你应该 试试看!)
我希望这最终能帮助您解决语法问题
按照您的示例,使用可变变量和循环:
open System
printfn "Guess the number"
let secretNum = System.Random().Next(1,101)
let mutable continueLooping = true
while continueLooping do
printfn "Please input your guess."
let mutable input = Console.ReadLine()
let result =
match Int32.TryParse input with
| (true, result) -> Some(result)
| (false, _) -> None
match result with
|Some guess -> printfn "You guessed: %A" guess
if guess < secretNum then printfn "Too small!"
else if guess > secretNum then printfn "Too big!"
else do
printfn "You win!"
continueLooping <- false
|None -> printfn "Your guess is not a valid number!"
[<EntryPoint>]
let main argv =
printfn "%A" argv
0 // return an integer exit code
我正在尝试从命令行输入中获取输入数字:
let mutable guess = Console.ReadLine() |> System.Int32.Parse
只要输入的是数字,这就可以正常工作;除非输入是字母字符串,例如 kdf
,程序将以 System.TypeInitilizationException
退出。
如何处理控制台输入中的字符串?
更新
我正在尝试用 F# 编写猜谜游戏。这是整个程序:
open System
printfn "Guess the number"
let secretNum = System.Random().Next(1,101)
let mutable continueLooping = true
while continueLooping do
printfn "Please input your guess."
let mutable input = Console.ReadLine()
let result =
match Int32.TryParse input with
| (true, result) -> Some(result)
| (false, _) -> printfn "Please input a number!"; None
let guess = Option.get result
printfn "You guessed: %A" guess
if guess < secretNum then printfn "Too small!"
else if guess > secretNum then printfn "Too big!"
else do
printfn "You win!"
continueLooping <- false
[<EntryPoint>]
let main argv =
printfn "%A" argv
0 // return an integer exit code
除了无法处理无效输入问题外,该程序的工作正常。我是编程新手,也许这对 .NET 程序员来说是一个很明显的问题。恐怕初学者经常有愚蠢的问题。
你看过Int32.TryParse了吗?
let parsed, guess = Console.ReadLine() |> System.Int32.TryParse
if parsed then ... else ...
我经常
match System.Int32.TryParse input with
| (true, number) -> ...
| (false, _) -> ....
对于 .net 中的所有 TryXY
模式也很有魅力 ;)
例子
F# Interactive for F# 3.1 (Open Source Edition)
Freely distributed under the Apache 2.0 Open Source License
For help type #help;;
> let tryInt input = match System.Int32.TryParse input with | (true, number) -> Some number | _ -> None;;
val tryInt : input:string -> int option
> tryInt "55";;
val it : int option = Some 55
> tryInt "no";;
val it : int option = None
>
备注
我的猜测是您想查询您的用户,直到他输入一个有效的整数。所以你可以使用我刚刚给你的函数来用一个递归的类循环函数来做到这一点:
let rec queryAnInt () =
printf "please input an integer "
let input = System.Console.ReadLine()
match System.Int32.TryParse input with
| (true, number) -> number
| _ -> printfn "sorry - you did not enter an integer"
queryAnInt ()
现在 queryAnInt ()
会要求用户输入一个整数,直到他给了一个,return 就这样(没有 Option
你似乎有问题)
你的程序
以下是我在您的程序中看到的一些内容:
首先是显而易见的事情:当你真的想在
main
方法和功能 - 这会让你很快陷入困境你将猜测匹配到
result
作为Option
只是为了在下一行Option.get result
中抛出所有你获得的东西,当result
是None
(当用户没有输入数字时)- 这 是你真正的问题你使用了一个全局可变变量和一个命令式循环——两者都是功能代码的味道
一个简单的重写(没有丑陋的可变)看起来像这样:
open System
let rec queryGuess () =
printf "please input your guess "
let input = Console.ReadLine()
match System.Int32.TryParse input with
| (true, number) when number >= 1 && number <= 100
-> number
| _ -> printfn "sorry - please enter a number between 1 and 100"
queryGuess ()
let rec guess secret nrTriesLeft =
if nrTriesLeft = 0 then printfn "Sorry you lost" else
match queryGuess () with
| g when g < secret ->
printfn "Too small!"
guess secret (nrTriesLeft - 1)
| g when g > secret ->
printfn "Too big!"
guess secret (nrTriesLeft - 1)
| g when g = secret ->
printfn "You win!"
| _ -> failwith "impossible case"
let game () =
printfn "Guess my secret number - it's between 1 and 100"
let secretNum = System.Random().Next(1,101)
guess secretNum 7 // 7 tries should always be enough - bonus question: why?
[<EntryPoint>]
let main _ =
game ()
0
这样你就可以很容易地扩展到让我们也只说一定数量的重试(只需稍微改变 guess
函数 - 你应该 试试看!)
我希望这最终能帮助您解决语法问题
按照您的示例,使用可变变量和循环:
open System
printfn "Guess the number"
let secretNum = System.Random().Next(1,101)
let mutable continueLooping = true
while continueLooping do
printfn "Please input your guess."
let mutable input = Console.ReadLine()
let result =
match Int32.TryParse input with
| (true, result) -> Some(result)
| (false, _) -> None
match result with
|Some guess -> printfn "You guessed: %A" guess
if guess < secretNum then printfn "Too small!"
else if guess > secretNum then printfn "Too big!"
else do
printfn "You win!"
continueLooping <- false
|None -> printfn "Your guess is not a valid number!"
[<EntryPoint>]
let main argv =
printfn "%A" argv
0 // return an integer exit code