【问题标题】:Can I make a record more flexible?我可以让记录更灵活吗?
【发布时间】:2011-03-11 06:51:48
【问题描述】:

谁能给我一个示例,说明如何更灵活地将数据插入到 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"}
    ]

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

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

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

【问题讨论】:

    标签: f# record


    【解决方案1】:

    如果您要在记录可用时指定记录的值,那么您需要将记录的字段设置为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

    【讨论】:

    • 您好先生,非常感谢您的回答。你能再帮帮我吗?我还是 F# 的新手。如果使用您的代码,这意味着名称值应该是一些字符串,对吗?先生,你能给我建议吗?如何学习这门语言,因为我试图通过编写书中的示例来学习,但是当我想编写一些应用程序时,我以代码结束,就像我使用命令式语言一样,最后我对这个概念的困惑结束了语言。我有点沮丧:)
    【解决方案2】:

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

    我想说在 F# 中使用 可变 记录并不是很习惯。

    Immutability 是一个相当大的主题 在这里解释一个答案,但是 简而言之:不变性意味着 你创建的对象永远不会改变: 他们保持原样 创建。在不变的世界里,当 你想“改变”一些东西,你 创建一个新的,然后扔掉 旧的。

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

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

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

    【讨论】:

    • 谢谢,是的,我已经知道使用您的代码不会更改数据。我只想编写简单的应用程序,就像我用 C++ 编写的那样,存储数据、删除数据、搜索数据并查看数据。在 C++ 中,我使用的是数组,这很容易......我只是尝试使用记录来制作这个简单的应用程序......但我发现它很难
    猜你喜欢
    • 2017-04-22
    • 2014-02-24
    • 2010-12-29
    • 1970-01-01
    • 2013-11-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-09
    • 2019-05-14
    相关资源
    最近更新 更多