有没有更好的方法将数据类型分配给字段?

时间:2018-03-29 01:46:21

标签: f#

我有一个像这样声明的变量:

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之外,没有任何约束。很明显,我缺少一些可以很容易地解决这个问题的基本知识(与语言功能相关的词汇等),但是我试图找出可能出现的问题的路障。

2 个答案:

答案 0 :(得分:3)

一种解决方案是为datatype

创建一个简单的包装器类型
type DataType =
| Byte
| Char
| Int
| Double
| String

(旁白:以这种方式重用语言关键字看起来很奇怪。)

Variable的声明随后变为:

type Variable = {
    name : string
    id : int
    datatype : DataType
}

以我们想要的方式声明variablelet 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" 直接放在代码的匹配部分。