为什么Scala编译器不能推断出Y
的类型参数A
为Int
?特征类型参数推断
trait X[A]
trait Y[A] extends X[A]
object Foo extends X[Int] with Y
有没有一种方法,我可以做到这一点,其中Y
可以了解的X
类型参数没有Foo
的声明,指明了两次?我无法获得自我打字的解决方案。
为什么Scala编译器不能推断出Y
的类型参数A
为Int
?特征类型参数推断
trait X[A]
trait Y[A] extends X[A]
object Foo extends X[Int] with Y
有没有一种方法,我可以做到这一点,其中Y
可以了解的X
类型参数没有Foo
的声明,指明了两次?我无法获得自我打字的解决方案。
Scala不支持类型声明中类型构造函数参数的推理(和省略)。这可能在未来的基于DOT演算的Scala版本中尝试统一类型参数和类型成员。
参见Odersky的演讲幻灯片The Trouble With Types(幻灯片29ff)的幻灯片。
您是否需要在此表单中输入参数?在某些情况下,可以使用以下解决方案:
trait X { type A /* type parameter as member */ }
trait Y extends X
object Foo extends Y { type A = Int /* equivalent to Y[Int] or X [Int] */ }
它可以用于定义。
trait X {
type A
def xfun: A
}
trait Y extends X { def tuple[K](k: K): (K, A) = (k -> xfun) }
object Foo extends Y {
def xfun = System.identityHashCode(this)
type A = Int
}
那么,如果测试:
scala> Foo.tuple("test")
res0: (String, Foo.A) = (test,2088931356)
对于一些使用情况,使用中间类可以解决这个问题:
import scala.reflect.runtime.universe._
abstract class XBase {
type A
def say(a : A) : Unit = println(a)
}
trait Y extends XBase {
override def say(a : A) : Unit = {
println("Hello ")
super.say(a)
}
}
class X[B : TypeTag] extends XBase {
type A = B
}
object Foo extends X[Int] with Y
为什么你不只是有'对象foo Y延伸[INT]'? –
为了扩展@ LimbSoup的答案,由于Y [A]已经扩展了X [A],所以你在X [A]中混合了两次。有什么特别的原因? –
公平的问题。我会需要几个'Y'类型,所以我要推迟到编译器以合理的方式对它们进行线性化处理(我认为这回答@ Mario的问题)。 –