【问题标题】:How can I delegate to a member in Scala?如何委派给 Scala 中的成员?
【发布时间】:2011-03-29 18:22:09
【问题描述】:

是否可以在 Scala 中编写如下内容:

trait Road {
  ...
}

class BridgeCauseway extends Road {
  // implements method in Road
}

class Bridge extends Road {
  val roadway = new BridgeCauseway()

  // delegate all Bridge methods to the `roadway` member
}

还是需要我一个一个地实现Road的每个方法,在roadway上调用对应的方法?

【问题讨论】:

  • 查看 Kevin Wright 的自动代理编译器插件。
  • @daniel - 有趣的是你应该这么说,我最近再次解雇了那个。 2.9 编译器的变化似乎能够支持我的原始设计。
  • @kevin - 太棒了!我认为每个人都需要这个代理功能。它绝对应该是 scala 的标准功能!我一直在写转发器,我之所以懒得安装编译器插件正是因为——我需要安装它,然后说服 sbt、idea 等 pp 透明地使用它。它是否适用于演示编译器(例如在想法中)?
  • 我刚刚向 GitHub 推送了一个更新,它现在都在针对 Scala 2.9.0.RC1 的 SBT 中。预计 24 小时内会有更好的文档和示例。
  • @Kevin Wright 太棒了 - 谢谢

标签: scala proxy


【解决方案1】:

最简单的方法是使用隐式转换而不是类扩展:

class Bridge { ... }
implicit def bridge2road(b: Bridge) = b.roadway

只要您不需要随身携带原始的Bridge(例如,您要将Bridge 存储在Road 的集合中)。

如果您确实需要再次取回Bridge,您可以在Road 中添加一个owner 方法,该方法返回一个Any,使用BridgeCauseway 的构造函数参数设置它,然后使用pattern-匹配以获取您的桥梁:

trait Road {
  def owner: Any
  ...
}

class BridgeCauseway(val owner: Bridge) extends Road { . . . }

class Bridge extends Road {
  val roadway = new BridgeCauseway(this)
  ...
}

myBridgeCauseway.owner match {
  case b: Bridge => // Do bridge-specific stuff
  ...
}

【讨论】:

  • 为什么不把隐式放在Bridge 的对象伴侣中呢?这将确保自动转发。当然,如果这些方法有副作用,它可能无法按预期工作。
  • @Daniel - 我没有因为没有同伴。但我同意,将隐含在 object Bridge { ... } 中通常是人们想要的。
  • 我知道隐式可以用 child.parent 替换 child,但是有没有办法使用隐式将 child 替换为 child.parent.parent?
  • @MichaelLafayette - 你需要举例说明你想做什么,因为你的第一个陈述并不完全正确。隐式可以用任何东西替换任何东西,并且对父类型没有特殊的访问权限。用 child.parent 替换 child 是继承!
【解决方案2】:

如果您可以将Bridge 设为trait,您将被排序。

scala> trait A {
     |   val x: String
     | }
defined trait A

scala> class B extends A {
     |   val x = "foo"
     |   val y = "bar"
     | }
defined class B

scala> trait C extends A { self: B =>         
     |   val z = "baz"               
     | }
defined trait C

scala> new B with C
res51: B with C = $anon$1@1b4e829

scala> res51.x
res52: java.lang.String = foo

scala> res51.y
res53: java.lang.String = bar

scala> res51.z
res54: java.lang.String = baz

【讨论】:

    猜你喜欢
    • 2013-03-10
    • 1970-01-01
    • 2016-07-12
    • 1970-01-01
    • 1970-01-01
    • 2017-07-29
    • 1970-01-01
    • 2018-09-30
    • 1970-01-01
    相关资源
    最近更新 更多