1

我遇到了这种我不明白的类型不匹配:

error: type mismatch;
found   : org.fluentlenium.core.domain.FluentList[_<:org.fluentlenium.core.domain.FluentWebElement]
required: org.fluentlenium.core.domain.FluentList[?0(in value $anonfun)] where type ?0(in value $anonfun) <: org.fluentlenium.core.domain.FluentWebElement
Note: org.fluentlenium.core.domain.FluentWebElement >: ?0, but Java-defined class FluentList is invariant in type E.
You may wish to investigate a wildcard type such as `_ >: ?0`. (SLS 3.2.10)

事实上,精确的“找到”值是以下类型:

org.fluentlenium.core.domain.FluentList[_<:org.fluentlenium.core.domain.FluentWebElement]=> 变体类型参数

我无法代表这样的情况,其中“找到”值是变体类型参数。我尝试了这个简单的代码段:

public class CarList<E extends Car> implements Collection<E> { // written in Java
   //overriden methods from Collection here
}

public class Car{} // written in Java

public Ferrari extends Car{} //written in Java

object Main extends App {  

   val carList: CarList[Car] = new CarList[Car]

   val l: CarList[Ferrari] = carList

}

发生的编译错误非常相似:

error: type mismatch;
found   : app.CarList[app.Car]     //but in this case, logically it's an invariant type: Car
required: app.CarList[app.Ferrari]
Note: app.Car >: app.Ferrari, but Java-defined class CarList is invariant in type E.
You may wish to investigate a wildcard type such as `_ >: app.Ferrari`. (SLS 3.2.10)
val l: CarList[Ferrari] = carList
                                     ^

如何修改我的代码片段以完全结束:

  • 与 ' 的错误相同类型的错误FluentList(在“找到”值中精确变体类型参数):
    found : app.CarList[_ :> app.Car]
  • 来自编译器的相同建议:
    You may wish to investigate a wildcard type such as _ >:

这样我就可以弄清楚问题的根源是什么?

4

1 回答 1

0

在您的 java 示例中,您似乎已经颠倒了两件事。您不能将汽车列表分配给法拉利列表。

考虑到这一点,我将片段解释如下:

class CarList[E <: Car]

class Car
class Ferrari extends Car

object Main extends App {

  val carList = new CarList[Ferrari]

  // this now throws a compiler error
  val l: CarList[Car] = carList
}

编译器错误如下:

type mismatch;
found: CarList[Ferrari] required: CarList[Car]
Note: Ferrari <: Car, but class CarList is invariant in type E.
You may wish to define E as +E instead.

所以编译器实际上帮助了我们。这个定义:

class CarList[E <: Car]

告诉编译器我们有一个扩展列表Car

但是,这并没有告诉编译器CarList[Ferrari]也扩展了CarList[Car]. 为了告诉编译器是这种情况,我们需要E+.

因此,为了解决这个错误,我们可以做两件事:

  1. 定义CarListCarList[+E],表示您不在乎其中的内容,但如果AextendsBCarList[A]可以考虑扩展CarList[B]
  2. 定义CarListCarList[+E <: Car],表示与 1 相同。但对 的类型有额外的限制,E因为它必须是Car

这个关于方差的问题可能会提供额外的信息。

于 2013-02-20T21:52:50.340 回答