有没有内置函数可以像printfn
一样从控制台读取输入?我只看到过使用System.Console.Read()
的方法,但它不如使用printfn
方便。
很遗憾,没有这样的内置函数。然而,正如Brian在Benjol答案的评论中提到的那样,可以自己构建一个scanf
函数。下面是一个快速草图,展示了如何定义一个sscanf
变体,尽管只实现了%s
占位符:
open System
open System.Text
open System.Text.RegularExpressions
open Microsoft.FSharp.Reflection
let sscanf (pf:PrintfFormat<_,_,_,_,'t>) s : 't =
let formatStr = pf.Value
let constants = formatStr.Split([|"%s"|], StringSplitOptions.None)
let regex = Regex("^" + String.Join("(.*?)", constants |> Array.map Regex.Escape) + "$")
let matches =
regex.Match(s).Groups
|> Seq.cast<Group>
|> Seq.skip 1
|> Seq.map (fun g -> g.Value |> box)
FSharpValue.MakeTuple(matches |> Seq.toArray, typeof<'t>) :?> 't
let (a,b) = sscanf "(%s, %s)" "(A, B)"
let (x,y,z) = sscanf "%s-%s-%s" "test-this-string"
printfn
函数本身依赖于编译器的魔法 - 你不能像它那样轻松地编写自己的 F# sscanf
函数。 - Tim Robinson结合TryParse()和split/regex是可以“开箱即用”的。
P.S. 我看过http://www.codeproject.com/KB/recipes/csscanf.aspx,它很有效 ;)
sscanf
版本时,扩展这段代码非常容易。请在此处查看结果:http://fssnip.net/4I - wmeyerMakeTuple
会出错... - Rei MiyasakaMakeTuple
行替换为:if matches.Length = 1 then matches.[0] :?> 't; else FSharpValue.MakeTuple(matches, typeof<'t>) :?> 't
。 - Rei Miyasaka