Reference a record from within itself during construction

限于喜欢 提交于 2019-12-10 20:10:08

问题


I am trying to create a record which uses one of the previously defined fields to calculate the value of another, within the same constructor. e.g.

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

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

When I try this it doesn't recognise Foo as already existing. I also can't reference Foo using myRecord.Foo, but that makes sense since myRecord hasn't been constructed yet. However I would've thought that Foo and Bar would be in the same scope, so Bar could access Foo, but apparently not.

The size of the Bar array depends on the value of Foo, so how is it possible to set up a record of this format?


回答1:


You cannot reference other fields, you shouldn't even take for granted the order of fields evaluation.

You can do it by additional let binding:

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

You can think of record construction expression as a function where right sides of assignments are parameters passed to that function.




回答2:


I would go with what @Bartek suggests and use local let binding to store all pre-computed values that you need to have before you can create the record.

That said (depending on your domain), you might also be able to change the structure of your record, so that you have one record with all the primary values and another record that contains the primary one and adds all secondary values:

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)}

Doing this just to make the construction a bit shorter would be silly, but if the primary record actually represents something in your domain, then this might be a good alternative.



来源:https://stackoverflow.com/questions/32406610/reference-a-record-from-within-itself-during-construction

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!