<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    莊周夢蝶

    生活、程序、未來
       :: 首頁 ::  ::  :: 聚合  :: 管理

    閉包使用的一個陷阱

    Posted on 2010-07-09 23:52 dennis 閱讀(1729) 評論(4)  編輯  收藏 所屬分類: 動態語言

    來源:http://moonbase.rydia.net/mental/blog/programming/the-biggest-mistake-everyone-makes-with-closures.html

    看下面的Ruby代碼
    = []
    for x in 1..3
      k.push(
    lambda { x })
    end

    執行
    k[0].call

    你可能預期返回1,實際的結果卻是3。這是為何?這是因為在迭代過程中共用了同一個context,導致k中的三個閉包都引用了同一個變量x。不僅僅Ruby有這個問題,python也一樣
    = [lambda: x for x in xrange(14)]
    k[0]()

    Javascript同樣如此

    var k = [];
    for (var x = 1; x < 4; x++) {
      k.push(function () { 
    return x; });
    }
    alert(k[0]())


    解決這個問題很簡單,就是將閉包包裝到一個函數里,建立新的context,那么迭代過程中生成的閉包所處的context不同:
    def make_value_func(value)
      
    lambda { value }
    end
    = (1..3).map { |x| make_value_func(x) }

    這個時候,k[0].call正確地返回1。

    這個問題并非在所有支持閉包的語言里都存在,例如scheme中就沒有問題

    (define k '())
    (do ((x 1 (+ x 1)))
        ((
    = x 4'())
      (set! k (cons (lambda () x) k)))
    (set! k (reverse k))

    ((car k)) 
    =>1


    Erlang也沒有問題
    K=[ fun()->X end || X <- [1,2,3]].

    lists:map(fun(F)
    -> F() end,K).

    再試試Clojure:
    (def k (for [i (range 1 4)] (fn [] i)))
    (map #(
    %) k)

    同樣沒有問題。這里Erlang和Clojure都采用列表推斷。





    評論

    # re: 閉包使用的一個陷阱  回復  更多評論   

    2010-07-10 00:40 by Rain Yang
    Ruby 1.9.x 不會再這樣了。

    # re: 閉包使用的一個陷阱[未登錄]  回復  更多評論   

    2010-07-15 14:46 by sin
    actionscript同樣問題

    # re: 閉包使用的一個陷阱  回復  更多評論   

    2012-12-22 15:57 by Zhiqiang.Zhan
    這不是閉包的缺陷,這是因為Ruby,Python還有JavaScript這些支持函數式等編程語言中的block都不能形成閉包作用域,而你拿來對比的Erlang和Clojure的例子很不恰當,它的等價形式相當于Ruby中的
    k = []
    (1..3).each do |x|
    k.push(lambda {x})
    end

    puts k[0].call

    而這個剛好是OK的。
    這是因為do...end block形成了閉包,但是for ...end中的語句沒有形成新的閉包。

    # re: 閉包使用的一個陷阱  回復  更多評論   

    2013-11-04 02:45 by 我傻逼我自豪
    js例:
    var a = [];
    for (var x = 4; x >= 0; x--) {
    a.push(function (x) {
    return x;
    });
    }
    alert(a[4]());
    主站蜘蛛池模板: 婷婷亚洲综合五月天小说| 综合久久久久久中文字幕亚洲国产国产综合一区首 | 国产成人免费福利网站| 亚洲精品456人成在线| 久久WWW免费人成一看片| 亚洲午夜久久久久久尤物| 久久免费看黄a级毛片| 亚洲免费二区三区| 午夜爱爱免费视频| MM1313亚洲国产精品| 又粗又硬又黄又爽的免费视频| 国产精品亚洲а∨无码播放麻豆| 俄罗斯极品美女毛片免费播放| 免费看又黄又爽又猛的视频软件| 亚洲日本在线观看视频| 9久久免费国产精品特黄| 日本亚洲视频在线| 精品女同一区二区三区免费站| 伊人久久五月丁香综合中文亚洲| 国产成人免费a在线视频app| 人妻18毛片a级毛片免费看| 亚洲人成网77777亚洲色| 51精品视频免费国产专区| 亚洲成人激情小说| 亚洲国产精品尤物YW在线观看| 日本免费A级毛一片| 亚洲成人在线免费观看| 麻豆精品国产免费观看| 成人一区二区免费视频| 亚洲电影唐人社一区二区| 国产成人青青热久免费精品| 搡女人免费免费视频观看| 亚洲av无码国产综合专区| 免费不卡中文字幕在线| 久久精品视频免费看| 亚洲精品无码av中文字幕| 亚洲老妈激情一区二区三区| 希望影院高清免费观看视频| 一区视频免费观看| 亚洲国产精品成人精品小说| 亚洲?V乱码久久精品蜜桃|