我目前有:
class X[+T: Numeric](val x: T)
abstract class M[N: Numeric, T <: X[N]] { // <- I'd like to remove N.
def apply(x: Int): T
final def row = (1 to 10).map(this(_))
}
我这样使用它:
class Y(x: Double, val y: Double) extends X[Double](x)
class Z extends M[Double, Y] { // <- So that this is simpler.
def apply(x: Int) = new Y(0.0, 0.0)
}
它的工作原理如下:
object testapp {
// row is properly polymorphic, allowing access to Y.y
def main(args: Array[String]): Unit = (new Z).row.map(r => println(r.y))
}
我希望 Z
更简单,以便我可以像这样使用 M
:
class Z extends M[Y] {
def apply(x: Int) = new Y(0.0, 0.0)
}
或者,甚至更好:
class Z extends M[Double] { // i.e. Meaning apply can return
def apply(x: Int) = new Y(0.0, 0.0) // any subclass of X[Double]
}
最佳答案
类型参数与类型成员的第三种方法是同时使用两者。
类型成员的优点是它不会污染子类的签名。如果类型成员是多余的(即使在具体类中),则可以保持抽象;如果需要,只有底层必须定义它。
import scala.collection.immutable.IndexedSeq
class X[+T: Numeric](val x: T)
abstract class M[+A: Numeric] {
type W <: X[A]
def apply(x: Int): W
final def row: IndexedSeq[W] = (1 to 10) map apply
def sumx: A = { // in terms of the underlying Numeric
val n = implicitly[Numeric[A]]
n fromInt (0 /: row)((s,w) => s + (n toInt w.x))
}
}
class Y(x: Double, val y: Double) extends X[Double](x)
class Z extends M[Double] {
type W = Y
def apply(x: Int) = new Y(0.0, 0.0)
}
def main(args: Array[String]): Unit = (new Z).row foreach (Console println _.y)
关于scala - 如何删除这个额外的类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13897885/