zoukankan      html  css  js  c++  java
  • [Erlang16]为什么要用MFA代替fun()–>end?

    MFA:Module Function Arguments.

    首先你要知道Module:Func(Args)和Func(Args)的区别在哪里?

    如果对细节感兴趣,可以通过这里了解:http://www.cnblogs.com/zhongwencool/p/erlang_hot_code.html

    总之:Erlang函数有local call和external call的区别,Local call 就是在函数在被定义的模块里面被调用,可以直接被调用: Func(Args); External call 就是显式的使用Module:Func(Args)来调用或import别的模块进来的调用.

    当同一个模块有2个版本被加载里,所有的local call都可以工作在当前版本状态,但是:external call只能调用到最新的版本!

    1.使用Fun的情景:

           1.1 先启动1个shell终端,分别名为test1:

    erl -name test1

           1.2 test1加载模块mfa_test.erl

    -module(mfa_fun).
    
    -export([cal/2,func/0]).
    
    cal(X,Y) ->
         X+Y.
    func() ->
           fun(X,Y) -> cal(X,Y) end.

    1.3在shell中输入:

    >Func = mfa_fun:func().
    #Fun<mfa_fun.1.52492151>
    >Func(1,2).
    3

    2.使用MFA的场景:

    改变mfa_test.erl中cal函数并重新加载这个模块:

    cal(X,Y) -> X*Y .

    1.5 再运行:

    >Func(1,2).
    3

    可以看到这个Func运行的local版本,如果把func改为以下版本:

    func() ->
           fun(X,Y) -> ?MODULE:cal(X,Y) end.

    那么结果是永远调用的最新版本代码,有兴趣可以自己验证下,你会感到好神奇,为什么Func变量是没有变化,但得到的结果却发生了变化。。。


    那么我们可以再进一步想一下:

    我们经常使用spawn(Func)来创建一个新的进程,如果我们永远不升级还好,如果热升级,会发生什么情况?

    这个local call的func,你怎么也改不了它,所以正常情况下最好使用:

    spawn(Mod,FuncName,Args)来创建进程,这样不会影响升级。

    再进一步,就是进程里面所有存local call都是无法被升级的,最佳实践就是一直用MFA就好!


    answer

         选择比努力重要,及时感恩,珍惜生活
  • 相关阅读:
    Master公式计算递归时间复杂度
    对数器的使用
    HTML翻转菜单练习
    剑指offer题目解答合集(C++版)
    HTML---仿网易新闻登录页
    两个有序数组中的中位数以及求第k个最小数的值
    算法之重建二叉树
    AFNetWorking 上传功能使用及源码分析
    图片Alpha预乘的作用[转]
    C#/.NET 学习之路——从入门到放弃
  • 原文地址:https://www.cnblogs.com/zhongwencool/p/mfa_fun.html
Copyright © 2011-2022 走看看