暴露成员对象的defs?

时间:2017-01-11 20:19:26

标签: scala

假设我有这样的特征:

trait A {
  def x: Long
  def y: Long
}

我有一个拿A的课,需要成为A:

case class B(a: A, foo: Foo, bar: Bar) extends A {
  override def x = a.x
  override def y = a.y
}

如果A有很多成员,这会很快烦人。是否有一种模式可以让我装饰"一个有foo和一个酒吧?

2 个答案:

答案 0 :(得分:0)

我想出了这样的代码,我不知道它对你有用吗:

object SelfAnnotationExample extends App{

  trait A {
   def x: Lon
   def y: Long
  }

  trait ExtendedA extends A { self: InstanceProvider[A] =>
    def x: Long = self.instance.x
    def y: Long = self.instance.y
  }

  trait InstanceProvider[A] {
    def instance: A
  }

  case class B(instance: A, foo: Any) extends ExtendedA with InstanceProvider[A]
  case class TestA(x: Long, y: Long) extends A

  val test = B(TestA(3, 4), 23)
  println(test.x)
  println(test.y)
}

我使用scala功能称为“自我类型”(如果我将其命名为错误,有人会纠正我)。 Trait InstanceProvider不限于此特定情况。此解决方案需要额外的特性ExtendedA定义,但A的每个具体实现都可以使用它。

答案 1 :(得分:0)

如果您想通过A上的B致电成员,并希望将A B部分传递给期待A的功能,您可以实现它使用从BA的隐式转换:

import scala.language.implicitConversions

object Main extends App{

  trait A {
    def x: Long
    def y: Long
  }

  def processA(a: A) = ()


  class Foo
  class Bar
  case class B(a: A, foo: Foo, bar: Bar)

  implicit def bToA(b: B): A = b.a

  case class TestA(x: Long, y: Long) extends A

  val test = B(TestA(3, 4), new Foo, new Bar)
  println(test.x)
  println(test.y)
  processA(test)
}