【问题标题】:Erlang and the recordsErlang 和记录
【发布时间】:2011-01-10 15:48:46
【问题描述】:

这段代码有什么问题? 我在person.name 中期待"titi",但我仍然有"toto"! 更明确一点,如何修改函数中的记录?

init1()->
    S=#person{name="toto"},   %record creation and field setting
    fct(S),
    io:format("~s~n",[S#person.name]).

fct(R)->
    R#person{name="titi"}.    %record updating

【问题讨论】:

    标签: erlang record


    【解决方案1】:

    你需要得到 fct() 的结果:

    init1()->
        S=#person{name="toto"},   %record creation and field setting
        S2 = fct(S),   % Get updated record
        io:format("~s~n",[S2#person.name]).
    
    fct(R)->
        R#person{name="titi"}.    %record updating
    

    【讨论】:

    • 可以声明全局记录吗?
    • @Bertaud,全局变量违反了 Erlang 的设计原则。即使变量是全局变量,由于 Erlang 中变量的不变性,您也无法修改它。如果您仍然想使用,可以使用 put 和 get 将记录存储在进程字典中(只能由进程访问,但无需在函数周围传递数据)或使用 ets 表。
    • 我的问题表述不正确,因为我的示例返回了记录。如果函数修改记录,计算并返回一个值,如何在调用者中读取修改后的记录?
    • 该函数无法更新 S,因为包括记录在内的所有变量都是不可变的。因此,就像 hdima 给您的示例一样,他将返回的修改后记录分配给 S2 变量。
    • 您需要将修改后的记录捕获到与@hdima 代码中不同的变量中
    【解决方案2】:

    Bertaud,我认为你有点超前了。在编写更多代码之前,您确实需要了解不变性的基础知识。 (即“变量”不会变化:您只能为它们赋值一次。)我建议您阅读免费在线指南“Learn You Some Erlang For Great Good”,地址为http://learnyousomeerlang.com/。涵盖变量基础的部分是http://learnyousomeerlang.com/starting-out-for-real#invariable-variables

    【讨论】:

      【解决方案3】:

      不可能过分强调 Erlang 中的所有数据都是不可变的。所以要在你原来的问题中做一些事情,你需要像@hdima 那样修改它。记录没有更新,而是重写。同理,Erlang 中没有全局数据,所有数据都属于一个进程。甚至 ETS 表也是如此,因为它们基本上表现得像一个进程,尽管它是一个没有显式通信的内置进程。

      因此,如果您使用流程字典或 ETS 表,则永远无法更新 数据 本身,只能更新字典/表。这意味着要修改字典/表中的某些数据,您基本上必须:

      1. “读取”数据
      2. 更新数据生成新数据
      3. 将新的“写”回字典/表中

      如果不将新数据写回字典/表中,它将丢失,就像您的新数据一样。

      【讨论】:

        【解决方案4】:

        在 fct() 中,您不会改变记录,但会为记录返回一个新值,该值需要进一步使用。如果您调用 fct(S) 而不处理返回值,那么您将丢失该新值(“titi”)。

        【讨论】:

          猜你喜欢
          • 2020-08-16
          • 1970-01-01
          • 1970-01-01
          • 2013-06-25
          • 2010-10-01
          • 1970-01-01
          • 2011-06-24
          • 2015-08-02
          • 1970-01-01
          相关资源
          最近更新 更多