3

以下输出 0 而不是我想要的结果,即 2。这看起来类似于 这个问题,但在这里我到处都使用括号。

object Test {
  implicit def x = List(1, 2)

  trait A[T] {
    def res(): Int = 0
    def makeResPlusOne(): Int = res() + 1    // All right
  }
  trait B[T] extends A[T] {
    def res()(implicit y: List[T]) = y.size
  }
  class AA extends A[Int]
  class BB extends B[Int]
}
val x: Test.A[Int] = new Test.BB
x.res() // Outputs 0 instead of 2.

我希望最后一个结果显然是 2 的大小y,但它输出 0。如果我将关键字添加override到 in 的方法中B[T],它表示它不会覆盖任何内容。如果我像这样将隐式参数添加到方法 res in A[T]...

object Test {
  implicit def x = List(1, 2)

  trait A[T] {
    def res()(implicit y: List[T]): Int = 0  // Added the implicit keyword.
    def makeResPlusOne(): Int = res() + 1    // Fails to compile.
  }
  trait B[T] extends A[T] {
    override def res()(implicit y: List[T]) = y.size
  }
  class AA extends A[Int]
  class BB extends B[Int]
}
val x: Test.A[Int] = new Test.BB
x.res() // Error

...它引发以下错误:

error: could not find implicit value for parameter y: List[Int]

我究竟做错了什么 ?如何在子类中获得隐式值的好处并且仍然能够重载超级方法?

编辑

如果我导入隐式,它会起作用。但是,我有方法makeResPlusOne(),它会在第二种情况下触发错误,但不会在第一种情况下触发。请告诉我如何正确定义此方法,该方法通常在编译时不需要隐式。_

 error: could not find implicit value for parameter y: List[T]
    def makeResPlusOne(): Int = res() + 1
                                ^
4

2 回答 2

4

你很接近:

object Test {
  implicit def list = List(1, 2)

  trait A[T] {
    def res()(implicit y: List[T]): Int = 0  // Added the implicit keyword.
  }
  trait B[T] extends A[T] {
    override def res()(implicit y: List[T]) = y.size
  }
  class AA extends A[Int]
  class BB extends B[Int]
}
import Test.list
val x: Test.A[Int] = new Test.BB
x.res() // Works!

您忘记导入隐式列表。请注意,我已经重命名了隐式,以避免在与变量导入时发生冲突x

编辑:

如果您希望def makeResPlusOne()(implicit y: List[T]): Int = res() + 1您需要List[T]在范围内隐含,那么您也必须添加(implicit y: List[T])

object Test {
  implicit def xx = List(1, 2)

  trait A[T] {
    def res()(implicit y: List[T]): Int = 0
    def makeResPlusOne()(implicit y: List[T]): Int = res() + 1 // Works now.
  }
  trait B[T] extends A[T] {
    override def res()(implicit y: List[T]) = y.size
  }
  class AA extends A[Int]
  class BB extends B[Int]
}
import Test.xx // import the implicit list
val x: Test.A[Int] = new Test.BB
x.res() // Works
于 2013-05-15T13:48:51.477 回答
2

This code works fine for me (notice I changed your implicit from a def to a val):

object Test {
  implicit val xx = List(1, 2)

  trait A[T] {
    def res()(implicit y: List[T]): Int = 0  // Added the implicit keyword.
  }
  trait B[T] extends A[T] {
    override def res()(implicit y: List[T]) = y.size
  }
  class AA extends A[Int]
  class BB extends B[Int]

  val x: Test.A[Int] = new Test.BB
  x.res()  
}

Not sure if this still meets your needs with the changes though. The underlying issue really was that, as the compiler was telling you, you did not have an implicit List[Int] in scope. My example moved the x.res() call into the Test object therefore bringing it into scope, but you could also have just imported the existing implicit into scope as mentioned by @Stephane Godbillon.

于 2013-05-15T13:10:57.260 回答