为什么Scala在第一种情况下警告类型擦除而不是第二种情况?

Owe*_*wen 10 scala pattern-matching type-erasure

我有两个函数(不是这些函数自原版以来都已编辑过 - 下面的一些答案是对原始函数的响应,它们返回了一系列的()):

def foo1[A](ls: Iterable[A]) : Iterator[A] =
    for (List(a, b) <- ls sliding 2) yield a

def foo2[A](ls: Iterable[A]) : Iterator[A] =
    for (a::b::Nil <- ls sliding 2) yield a
Run Code Online (Sandbox Code Playgroud)

我天真地认为是相同的.但是斯卡拉只对第一个有所减弱:

warning: non variable type-argument A in type pattern List[A]
is unchecked since it is eliminated by erasure
Run Code Online (Sandbox Code Playgroud)

我想我理解为什么它会给第一个错误:Scala认为我正在尝试使用该类型作为模式的条件,即List[B](_, _)如果B不从A继承,则匹配应该失败,除了这可以之所以发生,是因为在这两种情况下都会删除类型.

所以有两个问题:

1)为什么第二个不给出同样的警告?

2)是否有可能说服Scala在编译时实际知道该类型,因此不可能无法匹配?

编辑:我认为这回答了我的第一个问题.但我仍然对第二个感到好奇.

编辑:agilesteel在评论中提到

for (List(a, b) <- List(1,2,3,4) sliding 2) yield ()
Run Code Online (Sandbox Code Playgroud)

没有警告.这有什么不同foo1(不应该[Int]参数被删除与[A]参数相同)?

agi*_*eel 2

1)第二个不会产生警告,可能是因为您正在通过将元素添加到对象来构造列表(或模式)NilList该对象使用Nothing. 既然一切都是这样Nothing,那就没有什么可担心的;)但我不确定,真的在这里猜测。

2)你为什么不直接使用:

def foo[A](ls: Iterable[A]) =
    for (list <- ls sliding 2) yield ()
Run Code Online (Sandbox Code Playgroud)