在施工期间从自身内部引用记录

时间:2015-09-04 21:07:43

标签: f# record

我正在尝试创建一条记录,该记录使用之前定义的字段之一来计算同一构造函数中另一个字段的值。 e.g。

myRecordType = {Foo:int; Bar:int[]}

myRecord = {Foo = 5;
            Bar = Array.init Foo (fun i -> i)}

当我尝试此操作时,它不会识别Foo已存在。我也无法使用Foo来引用myRecord.Foo,但这是有道理的,因为myRecord尚未构建。但是,我会认为FooBar属于同一范围,因此Bar可以访问Foo,但显然不是。{/ p>

Bar数组的大小取决于Foo的值,那么如何设置此格式的记录呢?

2 个答案:

答案 0 :(得分:5)

你不能引用其他字段,你甚至不应该理所当然地认为字段评估的顺序。

你可以通过额外的let绑定来实现:

let myrecord = 
    let calcedFoo = 5
    { Foo = calcedFoo; Bar = Array.init calcedFoo id }

您可以将记录构造表达式视为一个函数,其中赋值的右侧是传递给该函数的参数。

答案 1 :(得分:0)

我会使用@Bartek建议并使用本地let绑定来存储您在创建记录之前需要具有的所有预先计算的值。

那说(取决于您的域名),您可能还可以更改记录的结构,以便您拥有一条包含所有主要值的记录和另一条包含主要记录的记录并添加所有次要值:

type MyRecordPrimary = { Foo:int }  
type MyRecord = { Primary:MyRecordPrimary; Bar:int[] }

let myPrim = { Foo = 5 }
let myRec = { Primary = myPrim; Bar = Array.init myPrim.Foo (fun i -> i)}

这样做只是为了让构造更短一些是愚蠢的,但如果主要记录实际上代表了你域中的某些内容,那么这可能是一个不错的选择。