我刚开始学习scala。我试图写一个函数来反转任何类型的List。
以下是代码:
def reverse [A] (l:List[A]):List[A] = {
val size:Int = lenList(l) // i have implemented this func separately
if (l.isEmpty) List()
else {
var newList = List()
for (i <- 1 to size)
{
var temp = l(size - i)
newList = newList :+ temp //type mismatch error here
}
newList
}
}'
编译上述代码时出现错误:
当我将newList
声明更改为var newList = List[A]()
时(与作为参数传递的List的类型相同),代码编译成功。
我的问题是:
当newList = newList :+ temp
类型为newList
且List[Nothing]
是temp
的元素时,为什么行type A
上存在类型不匹配?
如果声明中没有Found:List[A]
类型,编译器为什么会说List[A]
?
有人能告诉我出现这种特殊类型不匹配错误的原因吗?
此外,我想知道在更改声明时编译代码的原因是什么?
我的声明对最初抛出错误的声明有什么影响?
我相信在这种情况下,下面的错误信息是合理的
found:List[Nothing]
Required:List[A]
而不是我遇到的:
found:List[A]
Required:List[Nothing]
由于newList
类型的List[Nothing]
在语句中使用,而我尝试追加的元素是type A
,因此可以理解所需类型应为List[A]
。
答案 0 :(得分:2)
当你这样做时:
var newList = List()
newList
的类型为List[Nothing]
。如果您是scala的新手,Nothing
是其他所有类型的子类型。实际上,当我们必须向其写入任何数据时,它是无用的。我们会明白为什么会这样。
当您执行newList :+ temp
时,您将临时(A
类型)附加到List[Nothing]
。因此,对于编译器,类型推断预测此新列表必须是List[A]
类型。 (想想看,如果你创建一个狮子,鸟类和蛇的清单,你不会把这个新名单称为动物名单吗?)
因此生成的列表的类型为List[A]
。然后你尝试将它分配给自己(newList =
)。最初是List[Nothing]
。在scala中,使用var
,您可以更改值,但不能更改类型。在这里,我们尝试将newList
的类型从List[Nothing]
更改为List[A]
。
因此错误及其解释
答案 1 :(得分:0)
使用newList.+:(temp)
附加到列表