我有一个像这样声明的变量:
type Variable = {
name : string
id : int
datatype : Object
}
稍后,我想做这样的事情:
match variable.datatype with
| :? System.Byte -> printf "Byte"
| :? System.Double -> printf "Double"
| _ -> printf -> "Other type"
我最初的尝试是宣布variable
如此(A):
let variable = { name = "foo"; id = 0; datatype = System.Byte }
但是,这会导致datatype
包含<fun:variable@31>
之类的内容,match
的行为不符合要求 - 它总是会遇到“其他”情况。
我找到了一个解决方法,即
let variable = { name = "foo"; id = 0; datatype = Unchecked.defaultof<Byte> }
。但是,这并没有明确表达意图。
如何改进Variable
声明让datatype
包含Type
,以便(A)中的声明有效?
我正在尝试学习F#和.NET,这里没有涉及生产代码或作业。因此除了在基本值类型上具有期望的match
行为以及可能string
之外,没有任何约束。很明显,我缺少一些可以很容易地解决这个问题的基本知识(与语言功能相关的词汇等),但是我试图找出可能出现的问题的路障。
答案 0 :(得分:3)
一种解决方案是为datatype
:
type DataType =
| Byte
| Char
| Int
| Double
| String
(旁白:以这种方式重用语言关键字看起来很奇怪。)
Variable
的声明随后变为:
type Variable = {
name : string
id : int
datatype : DataType
}
以我们想要的方式声明variable
:let variable = { name = "foo"; id = 0; datatype = Byte }
。
然后以这种方式编写match
语句就可以完成工作:
match variable.datatype with
| Byte -> printf "Byte"
| Double -> printf "Double"
| _ -> printf "Other type"
答案 1 :(得分:1)
我想我有一半答案。如上所述Fyodor Soikin,我们可以使用System.Type而不是System.Object。
<package id="angularjs.TypeScript.DefinitelyTyped" version="6.5.6" targetFramework="net452" />
<package id="angular-material.TypeScript.DefinitelyTyped" version="1.6.4" targetFramework="net452" />
<package id="angular-ui.TypeScript.DefinitelyTyped" version="2.4.3" targetFramework="net452" />
编辑:我仍然不确定如何编写模式匹配。特别是,我无法弄清楚为什么我不允许将type Variable = {
name : string
id : int
datatype : System.Type
}
let variable = { name = "foo"; id = 0; datatype = typeof<System.Byte> }
let (|IsType|_|) (vartype: System.Type) (variable: Variable) =
if variable.datatype = vartype then Some () else None
let ByteType = typeof<System.Byte> // why do I need these let-bindings
let DoubleType = typeof<System.Double> // ahead of the match construct ?
match variable with
| IsType ByteType -> printf "Byte"
| IsType DoubleType -> printf "Double"
| _ -> printf "Other type"
直接放在代码的匹配部分。