我有以下非常设计的例子:
def f[T](t: T): T = {
t match {
case a : Int => a * 2
case _ => t
}
}
// Exiting paste mode, now interpreting.
<console>:14: error: type mismatch;
found : Int
required: T
case a : Int => a * 2
^
我的问题是:
Int
与T
?(a * 2).asInstanceOf[T]
之外还有其他策略可以操作多态返回相同类型的实例的事情,而对T
没有什么特别的了解吗? (保存类型类?)请注意以下类型类实现,甚至不那么优雅:
trait Manipulator[A] {
def manip(a: A): A
}
implicit object IntManip extends Manipulator[Int] {
override def manip(a: Int): Int = a * 2
}
implicit object WhateverManip extends Manipulator[Any] {
override def manip(a: Any): Any = a
}
def g[T](t: T)(implicit manipulator: Manipulator[T]) = {
manipulator.manip(t)
}
g(2)
g(2.3.asInstanceOf[Any])(WhateverManip)
我本可以取消asInstanceOf[Any]
已Manipulator
逆变,但......:
trait Manipulator[-A] {
def manip(a: A): A
}
// Exiting paste mode, now interpreting.
<console>:13: error: contravariant type A occurs in covariant position in type (a: A)A of method manip
def manip(a: A): A
答案 0 :(得分:2)
启用文字类型后,您可以拨打f[3](3)
。没有文字类型,在标准,当前,无选项Scala中,您仍然可以val a = new Integer(3); f[a.type](a)
。如果将类型参数T
修复为3
,则表示返回类型也必须为3
。类型3
仅存在值3
,这意味着返回3 * 2
是错误的。但3
也是Int
的一个实例,因此case a: Int
将适用于它。只有这不能证明T =:= Int
。
如果不使用类型大小写和类型转换,如果没有类型类,则可以与t
几乎无关。这实际上是parametricity的美丽。
如果您想拥有默认的回退实例,可以通过引入优先级来修复类型类别。
scala> :paste
// Entering paste mode (ctrl-D to finish)
trait Manipulator[A] {
def manip(a: A): A
}
object Manipulator extends LowerPriority {
implicit object IntManip extends Manipulator[Int] {
override def manip(a: Int): Int = a * 2
}
}
trait LowerPriority {
implicit def WhateverManip[T] = new Manipulator[T] {
override def manip(a: T): T = a
}
}
def g[T](t: T)(implicit manipulator: Manipulator[T]) = {
manipulator.manip(t)
}
// Exiting paste mode, now interpreting.
scala> g(2)
res0: Int = 4
scala> g(2.3)
res1: Double = 2.3