首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何利用隐式参数实现FRP?

如何利用隐式参数实现FRP?
EN

Stack Overflow用户
提问于 2016-10-08 03:48:21
回答 1查看 346关注 0票数 2

我正在学习马丁·奥德斯基的反应规划原理。当谈到一个简单玻璃钢框架的实现时,他在一开始给出了一个使用StackableVariable(即DynamicVairable)来跟踪当前更新的信号的方法,这一点我可以理解。但是在幻灯片的末尾,他提到了一个更清晰的解决方案是使用隐式参数而不是DynamicVariable。有人能告诉我怎么做吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-30 21:20:46

到幻灯片的链接对我没有用。当我尝试搜索它时,我现在使用1作为参考。

动态变量是一个线程局部变量,它保存当前计算什么信号的状态。这是必要的,以便信号的应用方法可以访问这些信息。让我们考虑下面的示例代码:

代码语言:javascript
复制
val a: Signal[Int] = ???
val b: Signal[Int] = ???
val xPlusY: Signal[Int] = Signal(a() + b())

在这里,当调用a()时,它将自己添加到当前计算信号的依赖项列表中。由于其他任何地方都无法访问这些信息,因此我们基本上使用线程本地a.k.a。全局变量

这个解决方案有一些问题。例如,如果不在任何a()中,我们也可以调用Signal()。另外,我们必须使用一个全局变量。

解决方案是通过一个隐式参数将此信息提供给a():我们将签名更改为

代码语言:javascript
复制
Signal[T]#apply(): T

代码语言:javascript
复制
Signal[T]#apply()(implicit triggeredBy: Signal[_])

(请注意,我们可能希望使用一些新类型的TriggeredBy来封装一个信号)

这样,该方法的实现将可以访问其原始信号,而不需要全局/线程局部变量。

但现在我们必须以某种方式提供这个隐含的信息。选项之一是将信号创建函数的签名更改为

代码语言:javascript
复制
def Signal.apply[T](fun: => T): Signal[T]

代码语言:javascript
复制
def Signal.apply[T](fun: Signal[_] => T): Signal[T]

不幸的是,我们的示例代码的语法必须改变,因为我们必须提供一个函数而不是一个主体:

代码语言:javascript
复制
val xPlusY: Signal[Int] = Signal { implicit triggeredBy => a() + b() }

对于这个问题,有几种解决办法:

  • 等待隐式函数类型已经实现2。这种情况可能不会在短期内发生,但它将允许我们按以下方式编写Signal.apply签名: def Signal.applyT:SignalT 然后能够再次编写Signal(a() + b())
  • 使用一些宏魔术将表单Signal(a() + b())的代码转换为Signal.internalApply(implicit triggeredBy => a() + b())代码。这意味着,Signal.apply现在是一个宏。这就是scala.rx3.所走的道路,从使用的角度来看,它运行得很好。这也允许我们再次编写Signal(a() + b())

更新:指向隐式函数的更新链接,解释到更详细的博客文章

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39928480

复制
相关文章

相似问题

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