の暗黙的な値の提供は、要求しているコードが一度だけ実行されるコードブロック内にある場合にのみ、自動的にマクロ魔法的にrx.Ctx.Owner
行われるようです。これには、s 、s、s などが含まれます。rx.Ctx.Owner
object
val
lazy val
val c = ...
この例は、一度しか評価されないため、問題なくコンパイルされます。
object Once {
val a = Var(1)
val b = Var(2)
//no need to provide `implicit ownerCtx: rx.Ctx.Owner`
val c = Rx {
a() + b() -> Rx {a() - b()}
}
}
同様に、問題で言及されている例ですが、scala REPL に貼り付けられています。
このような制限は、scala.rxライブラリのRx リークの問題によるものです。これらは、高次の Rx 変数 (別の Rx 変数を含む Rx 変数) を作成するときに存在します。リークの問題の詳細については、sala.rx プロジェクト サイトを参照してください。
リークの救済策として - の概念rx.Ctx.Owner
が導入され、voodo-macro が導入されました。この scala.rx からの抜粋は、興味深い部分を示しています。Owner
コンパニオン オブジェクトと に注意してimplicit def voodoo: Owner
ください。
object Owner extends Generic[Owner]{
object Unsafe extends Owner(???){
implicit val Unsafe: Ctx.Owner.Unsafe.type = this
}
/**
* Dark magic. End result is the implicit ctx will be one of
* 1) The enclosing RxCtx, if it exists
* 2) RxCtx.Unsafe, if in a "static context"
* 3) RxCtx.CompileTime, if in a "dynamic context" (other macros will rewrite CompileTime away)
*/
@compileTimeOnly("@}}>---: A rose by any other name.")
implicit def voodoo: Owner = macro Factories.automaticOwnerContext[rx.Ctx.Owner]
}
コードの静的ブロックは一度しか評価されず、リークの影響を受けないことが判明しました。voodoo
これが、コンパイラが暗黙的な検索を許可する理由です。そのような方法でコードを設計してみてください。
コードが静的コードではなく、コードが 1 回しか評価されないことが確実な場合 (テスト中のスクリプトなど)、一般的な解決策は、コンパニオン オブジェクトUnsafe
から暗黙的なインスタンスを提供することです。Owner
あとはインポートするだけimport Ctx.Owner.Unsafe._
です。
ここでは、scala.rx ソースのBasicTestsでどのように行われるかを示します。
package rx
import util.{Failure, Success}
import utest._
import acyclic.file
object BasicTests extends TestSuite{
//We dont care about potential Rx leaks in BasicTest
import Ctx.Owner.Unsafe._
...