<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]());
    主站蜘蛛池模板: 亚洲AV中文无码乱人伦| 亚洲精品在线免费观看视频| 亚洲成人精品久久| xxxxx做受大片在线观看免费| 又黄又大又爽免费视频| 亚洲丁香色婷婷综合欲色啪| 国产在线观看免费视频软件| 国产精品亚洲A∨天堂不卡| 亚洲欧美日韩中文字幕在线一区 | 2020年亚洲天天爽天天噜| 亚洲视频免费观看| 日本亚洲免费无线码| 日韩免费无码一区二区视频| 亚洲国产精品不卡在线电影| 久久久久成人精品免费播放动漫| 久久亚洲精品成人综合| 最近2018中文字幕免费视频| 亚洲国产高清美女在线观看| 韩国免费A级毛片久久| 亚洲av中文无码乱人伦在线播放| 污视频在线免费观看| 亚洲综合小说另类图片动图| 国产jizzjizz免费视频| 中文字幕成人免费高清在线| 日韩精品一区二区亚洲AV观看| 四虎永久在线精品免费观看视频| 亚洲国产av玩弄放荡人妇| 亚洲AV日韩精品一区二区三区| 亚洲欧美中文日韩视频| 亚洲AV无码一区二区三区在线观看| AAA日本高清在线播放免费观看| 亚洲色图.com| 国产成人免费全部网站| 久久久精品视频免费观看 | 在线观看亚洲AV日韩AV| 亚洲精品尤物yw在线影院| 95免费观看体验区视频| 亚洲AV永久无码精品一福利| 国产亚洲精品va在线| 成人免费无遮挡无码黄漫视频| 国产一级高青免费|