我可以使记录更灵活吗?

时间:2011-03-11 06:51:49

标签: f# record

有人能举例说明如何将数据插入F#记录更灵活吗?

我经常看到使用这样的记录的例子:

type Employee = {mutable name:string; mutable id:string}

let data = 
    [{name = "Thomas";id = "000"};
     {name = "Johny";id = "001"};
     {name = "Lucky";id = "002"};
     {name = "Don";id = "003"}
    ]

我们不能从没有数据开始,然后将数据插入记录中吗?

(我的意思是没有像示例中那样声明数据的值,例如:程序正在运行并要求我们插入数据)

我们可以用记录做这样的事吗?

2 个答案:

答案 0 :(得分:4)

如果您正在谈论在记录可用时指定记录的值,那么您需要创建记录option的字段,以便您可以表示缺少值的事实。我将使用不可变记录,因为这在功能样式中更常见:

type Employee = { Name:option<string>; ID:option<string> }  

现在,您可以创建仅包含ID的记录,并在用户输入时添加名称:

let empty = { Name = None; ID = Some 123 }
let name = // read name from user
let full = { empty with Name = name }

如果您正在谈论在列表可用时将项目添加到列表中,那么您有几个选项。直接的一个是编写一个递归函数,重复读取记录并构建一个列表:

let rec readData i records = 
  let name = // read name from user 
  if name <> "" then
    // Create new record and add it to our list
    let itm = { Name = name; ID = string i }
    readData (i + 1) (itm::records)
  else 
    // Return records that we collected so far in the right order
    records |> List.rev

或者,您也可以使用序列表达式(例如,参见实际功能编程的free Chapter 12(PDF))。如果用户交互涉及等待事件(例如鼠标单击),那么您仍然可以使用此样式,但是您需要将所有内容包装在异步工作流中并使用Async.AwaitEvent

答案 1 :(得分:1)

你是否经常看到了这样的例子?

我会说在F#中使用 mutable 记录并不是很惯用。

  

Immutability是一个相当大的主题   在这里一个答案解释,但是   简而言之:不变性意味着   您创建的对象永远不会更改:   他们保持原样   创建。在不变的世界里,何时   你想要'改变'某事,你   创造一个新的,扔掉   旧的。

无论如何,如果我理解你的问题,你实际上是在谈论变异data,而不是记录。所以,你可以:

let data = []
let data = {name = "Thomas";id = "000"} :: data
let data = {{name = "Johny";id = "001"} :: data

但是在这种情况下,你并没有真正“改变”数据,你只是每次创建一个新列表并将数据指向它。