我正在尝试使用F#中的Type来创建原始值。代码如下所示,但不起作用。我会非常感谢所有的帮助和感谢。
open System
let getvalue (t: Type) (v: string) : obj =
match box t with
| :? int -> let r = (int) v
box r
| :? byte -> let r = (byte) v
box r
| :? sbyte -> let r = (sbyte) v
box r
| :? int16 -> let r = (int16) v
box r
| :? uint32 -> let r = (uint32) v
box r
| :? int64 -> let r = (int64) v
box r
| :? uint64 -> let r = (uint64) v
box r
| :? double -> let r = (double) v
box r
| :? float32 -> let r = (float32) v
box r
| :? decimal -> let r = (decimal) v
box r
| :? char -> let r = (char) v
box r
| :? string -> v :> obj
| _ ->
let s = sprintf "Error unknown type %A" t
raise (ApplicationException(s))
答案 0 :(得分:5)
无需重新发明轮子,请使用Convert.ChangeType。
如果您如此倾向,那么您可以编写一个包装器,让编译器自动确定类型。
let inline getValue<'a> (s:string) = // limit to string only if desired
System.Convert.ChangeType(s, typeof<'a>) :?> 'a
let x = getValue "1" + 1.2 // no need to explicitly state "float" anywhere here
printfn "%A" x // 2.2
答案 1 :(得分:3)
由于t
总是一个Type
值,因此永远不会属于int
类型,{{1} },byte
等。这就是函数总是引发异常的原因;那些其他比赛永远不会成真。
相反,您必须将decimal
与t
,typeof<int>
等进行比较。但是,您无法使用常量模式为此,因为typeof<byte>
,typeof<int>
等不是常量。
相反,您可以使用typeof<byte>
表达式:
if .. elif .. else
如果确实想要使用模式匹配,您可以考虑将其隐藏在active pattern之后,但就个人而言,我认为这不值得。