使用存在类型键入推断

时间:2016-07-28 05:00:57

标签: scala generics

我有一个通用特征SomeTrait定义如下:

trait SomeTrait[T] {
  def foo(t: T): String
}

方法barqux如此:

def bar[T](t: SomeTrait[T]): T
def qux: List[SomeTrait[_]]

我无法控制上述情况。我正在尝试对qux返回的列表进行操作,如此

qux map { x => x.foo(bar(x))}

然而,编译器抱怨这些类型不匹配。据我所知,这应该没事。

我尝试添加一个通用方法(签名[T](SomeTrait[T])String),并调用它来完成工作,但编译器仍抱怨。我可以像这样投下我的方式:

qux map { x =>
  val casted = x.asInstanceOf[SomeTrait[T forSome { type T }]] // !!!
  casted.foo(bar(casted))
}

但这更令人费解,因为x已经有类型SomeTrait[_]SomeTrait[T forSome { type T }]意味着同样的事情。我所知道的唯一区别是前者是后者的简写,它使编译器创建自己的合成名称。我希望有更好的方法来做到这一点。我见过this question,但我认为它不适用。

1 个答案:

答案 0 :(得分:3)

执行此操作的正确方法是使用类型变量为T指定名称:

qux map { case x: SomeTrait[t] => x.foo(bar(x)) }

这样编译器就会知道bar(x): t,因此它是x.foo的可接受参数。

或者,或者,您可以将foobar合并到一个方法中(请记住,方法可以是本地的,因此您可以在需要的地方定义它):

def fooOfBar[T](x: SomeTrait[T]) = x.foo(bar(x))
qux map { fooOfBar(_) }