我有一个通用特征SomeTrait
定义如下:
trait SomeTrait[T] {
def foo(t: T): String
}
方法bar
和qux
如此:
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,但我认为它不适用。
答案 0 :(得分:3)
执行此操作的正确方法是使用类型变量为T
指定名称:
qux map { case x: SomeTrait[t] => x.foo(bar(x)) }
这样编译器就会知道bar(x): t
,因此它是x.foo
的可接受参数。
或者,或者,您可以将foo
和bar
合并到一个方法中(请记住,方法可以是本地的,因此您可以在需要的地方定义它):
def fooOfBar[T](x: SomeTrait[T]) = x.foo(bar(x))
qux map { fooOfBar(_) }