首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在ownerCtx中获取隐式rx.Ctx.Owner : scala.rx

如何在ownerCtx中获取隐式rx.Ctx.Owner : scala.rx
EN

Stack Overflow用户
提问于 2016-09-26 13:50:59
回答 1查看 318关注 0票数 1

下面是使用0.3.1版本中的scala.rx的基本hello world示例。

由于缺少implicit ownerCtx: rx.Ctx.Owner,它没有编译。我怎么得到这个例子?

代码语言:javascript
复制
import rx._
val a = Var(1)
val b = Var(2)
val c = Rx{ a() + b() }

This Rx might leak! Either explicitly mark it unsafe (Rx.unsafe) or ensure an implicit RxCtx is in scope!
[error]     val c = Rx{ a() + b() }
[error]               ^
[error] one error found

有趣的是,在scala中,它可以工作!?

代码语言:javascript
复制
scala> import rx._
val a = Var(1)
val b = Var(2)
val c = Rx{ a() + b() }
import rx._

scala> a: rx.Var[Int] = Var@2c(1)
scala> b: rx.Var[Int] = Var@2f(2)
scala> c: rx.Rx.Dynamic[Int] = Rx@d1(3)
scala> 

更新:

添加implicit val ctx = Ctx.Owner.Unsafe代码后编译。但这看起来不安全..。

EN

回答 1

Stack Overflow用户

发布于 2016-09-26 19:32:32

似乎提供rx.Ctx.Owner的隐式值只在请求rx.Ctx.Owner的代码在代码块内时才会自动宏完成,而代码块只运行一次。这包括objects、vals、lazy vals等。

这个示例编译时没有问题,因为val c = ...只计算一次。

代码语言:javascript
复制
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中。

这种限制是由于Rx泄漏问题scala.rx库中造成的。当创建更高顺序的Rx变量(Rx变量,其中包含另一个Rx变量)时,它们就会出现。有关泄漏问题的更多信息可以在sala.rx项目场地上阅读。

作为对泄漏的补救,引入了rx.Ctx.Owner和voodo宏的概念.这个来自scala.rx的超量显示了有趣的部分。注:Owner伙伴对象和implicit def voodoo: Owner

代码语言:javascript
复制
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允许编译器找到隐式的原因。尝试以这样的方式设计代码。

如果代码不是静态代码,并且您确信代码只计算一次(例如测试中的脚本),常见的解决方案是从Unsafe伙伴对象提供Owner隐式实例。那么只需导入import Ctx.Owner.Unsafe._即可。

这里是如何在BasicTests of scala.rx源代码中完成的:

代码语言:javascript
复制
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._
  ...
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39704740

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档