我已尽力了解下限工作在类型参数化方面的相关性,但无法理解它。
这里是一些下行示例代码。
class Queue[+T] (
private val leading: List[T],
private val trailing: List[T]
) {
private def mirror = {
if (leading.isEmpty){
new Queue(trailing.reverse, Nil)
}
else
this
}
def head = mirror.leading.head
def tail = new Queue(mirror.leading.tail,
mirror.trailing)
/* ====Wrong definition for enqueue====
* def enqueue (item: T) =
* new Queue(leading, item :: trailing)
*/
def enqueue[U >: T] (item: U) =
new Queue[U](leading, item :: trailing)
}
class Fruit (val name: String) {
override def toString = name
}
class Orange extends Fruit("orange")
class Apple extends Fruit("apple")
val queueOrange: Queue[Orange] = new Queue[Orange](Nil, Nil)
queueOrange.enqueue(new Apple())
queueOrange.enqueue(new Orange())
queueOrange.enqueue(new Fruit("PineApple"))
val queueFruit: Queue[Fruit] = queueOrange
queueFruit.enqueue(new Orange())
queueFruit.enqueue(new Apple())
queueFruit.enqueue(new Fruit("Pineapple"))
而here是执行上述代码的结果。
我有一些与上述代码和结果相关的问题。
我无法理解代码queueOrange.enqueue(new Apple())如何成功执行。据我所知,lowerbound限制了enqueue方法中的类型U应该是T的超类型,这是一个下限。然而,Apple和Orange都是同一个超类Fruit的兄弟姐妹。
我无法理解queueOrange.enqueue(新Apple())如何返回Queue [Fruit],即使我们将新的Orange()作为enqueue的参数提供。我认为这可能是因为Orange继承了Fruit,但是我无法理解整体机制是如何工作的,这会让问题1和问题2发生。
当我使用queueOrange和queueFruit在上面的代码中执行相同的操作时,我无法理解为什么结果会有所不同。
答案 0 :(得分:1)
据我所知,下限限制了enqueue方法中的类型
的超类型SERVER_DATE LOCAL_TIME LOCAL_TIME_4HRS_BACK -------------------- -------------------- -------------------- 3/16/2018 5:08:59 3/16/2018 14:38:59 3/16/2018 10:38:59
应该是U
这不是完整的定义。 T
,或其任何祖先必须是U
的超类型。如果我们将该表达式赋值给某个值,您会看到推断类型为T
,因为编译器足够聪明,可以查看对象图。
如果您想确保Queue[Fruit]
是U
的直接超类型,则需要稍微修改一下您的方法:
T
这样,编译器首先将def enqueue[U](u: U)(implicit ev: T <:< U)
绑定到U
,然后搜索隐式证据,使Apple
失效。