F#可选记录字段

aka*_*nom 13 f# record optional

我有一个F#记录类型,并希望其中一个字段是可选的:

type legComponents = {
    shares : int<share> ;
    price : float<dollar / share> ;
    totalInvestment : float<dollar> ;
}

type tradeLeg = {
    id : int ;
    tradeId : int ;
    legActivity : LegActivityType ;
    actedOn : DateTime ;
    estimates : legComponents ;
    ?actuals : legComponents ; 
}
Run Code Online (Sandbox Code Playgroud)

在tradeLeg类型中,我希望actuals字段是可选的.我似乎无法弄明白,也无法在网上找到可靠的例子.看起来这应该很容易

let ?t : int = None
Run Code Online (Sandbox Code Playgroud)

但我真的似乎无法让这个工作.呃 - 谢谢你

Ť

Tom*_*cek 22

正如其他人指出的那样,你可以使用这种'a option类型.但是,这不会创建可选的记录字段(在创建时不需要指定其值).例如:

type record = 
  { id : int 
    name : string
    flag : bool option }
Run Code Online (Sandbox Code Playgroud)

要创建该record类型的值,您仍需要提供该flag字段的值:

let recd1 = { id = 0; name = "one"; flag = None }     
let recd2 = { id = 0; name = "one"; flag = Some(true) } 

// You could workaround this by creating a default record 
// value and cloning it (but that's not very elegant either):
let defaultRecd = { id = 0; name = ""; flag = None }     
let recd1 = { defaultRecd  with id = 0; name = "" }
Run Code Online (Sandbox Code Playgroud)

不幸的是,(据我所知)你不能创建一个记录,它有一个真正的选项字段,你可以在创建它时省略它.但是,您可以使用带有构造函数的类类型,然后您可以使用?fld语法来创建构造函数的可选参数:

type Record(id : int, name : string, ?flag : bool) = 
  member x.ID = id
  member x.Name = name
  member x.Flag = flag

let rcd1 = Record(0, "foo")
let rcd2 = Record(0, "foo", true)
Run Code Online (Sandbox Code Playgroud)

rcd1.Flag将是的类型,bool option您可以使用模式匹配(如Yin Zhu所示)使用它.记录和像这样的简单类之间唯一值得注意的区别是,您不能使用with语法来克隆类,并且该类不会(自动)实现结构比较语义.


Cha*_*ion 6

怎么样Option

type tradeLeg = {
    id : int option;
    tradeId : int option;
    legActivity : LegActivityType option;
    actedOn : DateTime option;
    estimates : legComponents option;
    actuals : legComponents option; 
}
Run Code Online (Sandbox Code Playgroud)