Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Created December 17, 2019 13:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xuwei-k/1b4673f06460c742506f612a38c6d6c4 to your computer and use it in GitHub Desktop.
Save xuwei-k/1b4673f06460c742506f612a38c6d6c4 to your computer and use it in GitHub Desktop.

単純な(リークするかもしれない)実装

def foo(lazyList: LazyList[A]) = {
  
  // Scala 2.13のlazyListだとnewLLとかいう名前のやつ
  Function0を引数に取るやつ {
    引数のlazyList使った実装
  }
}

上記のやつを、コンパイラはこんな感じに展開する、というイメージ

def foo(lazyList: LazyList[A]) = {
  Function0を引数に取るやつ {
    new Function0[A, B] {
      // フィールドにvalで保持されるコードをコンパイラが生成するイメージ
      // valで保持されちゃったら、所属しているFunction0自体がGCされるまでずっとGCされない
      private[this] val lazyListの参照 = lazyList
    
      def apply() = {
        // 実装
      }
    }
  }
}

上記の問題を解決するための、varを使った辛い工夫

def foo(lazyList: LazyList[A]) = {
  var ll = lazyList
  Function0を引数に取るやつ {
    // 引数のlazyListは直接参照しないで実装を書く
    // "var ll"のほうを参照する
    // llが必要なくなったらnullあるいは他のものを代入してGCされるようにする
    //
    // コンパイラが十分賢ければこのくらいのこと勝手にやってくれ、という話ではある・・・?
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment