首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Scala和Generics的奇异性

Scala和Generics的奇异性
EN

Stack Overflow用户
提问于 2013-02-20 12:27:39
回答 1查看 333关注 0票数 1

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

代码语言:javascript
复制
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] =>变型参数

我无法表示这样的情况,在这种情况下,“查找”值是一个可变类型参数。我尝试了这个简单的代码片段:

代码语言:javascript
复制
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

}

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

代码语言:javascript
复制
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 _ >:

这样我才能弄清楚这个问题的根源是什么?

EN

回答 1

Stack Overflow用户

发布于 2013-02-20 21:52:50

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

考虑到这一点,我将代码片段解释为:

代码语言:javascript
复制
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
}

编译器错误如下:

代码语言:javascript
复制
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.

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

代码语言:javascript
复制
class CarList[E <: Car]

告诉编译器我们有一个扩展Car的东西列表。

但是,这并不能告诉编译器CarList[Ferrari]也扩展了CarList[Car]。为了告诉编译器这种情况,我们需要将E+进行协变。

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

  1. CarList定义为CarList[+E],表示您不关心它们中的内容,但是如果A扩展了B,那么CarList[A]可以被视为扩展CarList[B]
  2. CarList定义为CarList[+E <: Car],与1相同,但在E类型上有额外的限制,因为它必须是Car

This question about variance可能会提供更多信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14979866

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档