首页 文章

使用implicits在特征层次结构的多个级别注入方法

提问于
浏览
0

我正在尝试采用现有的特征层次结构(我无法控制)并在顶层注入一个方法(然后在层次结构中需要自定义处理的每个点上覆盖该方法) . 隐含地使用这些特征 . 下面是一个精简的示例,显示了特征层次结构设置和隐式用法;然后我(失败)尝试注入一个方法 .


使用未实现的方法定义父特征,具有指定类型的子特征和方法的实现形式 . 创建一个隐含的儿童特质 .

trait ParentTrait[T] {
  def doSomething1(x: T): T
}

trait ChildTrait extends ParentTrait[Double] {
  override def doSomething1(x: Double): Double = {
    return x + 1.0
  }
}

implicit object ChildTrait extends ChildTrait

定义一个类和函数以隐式使用Parent Trait并调用该方法 .

class Utilizer1() {
  def utilize[T](x: T)(implicit trt: ParentTrait[T]): Unit = {
    println(trt.doSomething1(x))
  }
}

调用方法,指定将隐式拾取Child Trait的类型(Double) . (这很好 . )

new Utilizer1().utilize[Double](1.0)

这里的东西不起作用:在父Trait上“注入”一个新方法,并在Child Trait中覆盖它 . (显然,这不是正确的方法 - 如何完成这一部分?)

implicit class BetterParentTrait[T](trt: ParentTrait[T]) {
  def doSomething2(x: T): T = ???
}
implicit class BetterChildTrait(trt: ParentTrait[Double]) extends BetterParentTrait[Double](trt) {
  override def doSomething2(x: Double): Double = {
    return x + 2.0
  }
}

定义一个类和函数以隐式使用Parent Trait并调用SECOND方法 .

class Utilizer2() {
  def utilize[T](x: T)(implicit trt: ParentTrait[T]): Unit = {
    println(trt.doSomething2(x))
  }
}

调用方法,指定类型(Double) . 它不会隐式地拾取Child Trait而是抛出NotImplementedError . 所以它确实找到了doSomething2方法(没有编译错误),但它不尊重层次结构并使用顶层的未实现形式 .

new Utilizer2().utilize[Double](1.0)

2 回答

  • 0

    您正在执行聚合而不是继承 .

    BetterParentTrait[T](trt: ParentTrait[T])

    这意味着 utilize 方法将看不到您的隐式类,因为它具有不同的父/接口 . 它必须实现 ParentTrait 类才能隐式传递给上述方法 .

    implicit class BetterParentTrait[T] extends ParentTrait[T]{
      def doSomething(x: T): T = ???
      def doSomething2(x: T): T = ???
    }
    
  • 0

    这有帮助吗?

    object MainUtilizers {
    
      trait ParentTrait[T] {
        def doSomething1(x: T): T
      }
    
      trait ChildTrait extends ParentTrait[Double] {
        override def doSomething1(x: Double): Double = {
          return x + 1.0
        }
      }
    
    
      trait BetterParentTrait[T] {
        def doSomething2(x: T): T = ???
      }
    
      trait  BetterChildTrait extends BetterParentTrait[Double] {
        override def doSomething2(x: Double): Double = {
          return x + 2.0
        }
      }
    
      //implicit object ChildTrait extends ChildTrait // Commented to avoid 2 implicits for ParentTrait[Double]
    
      implicit object BetterChildTrait extends BetterChildTrait with ChildTrait
    
      class Utilizer1() {
        def utilize[T](x: T)(implicit trt: ParentTrait[T]): Unit = {
          println(trt.doSomething1(x))
        }
      }
      class Utilizer2() {
        def utilize[T](x: T)(implicit trt: BetterParentTrait[T]): Unit = {
          println(trt.doSomething2(x))
        }
      }
    
      def main(args: Array[String]) {
        new Utilizer1().utilize[Double](1.0)
    
        new Utilizer2().utilize[Double](1.0)
      }
    }
    

相关问题