在Kotlin中创建列表的这些方式有什么不同?我的结果1是有效的,但结果2是无效的


val list1 = listOf(1,2,3,4,5,6,7,8,9)
val list2 = listOf(1..9)

/*我的结果1是有效的,但结果2给出了错误*/

val result1= list1.filter{i -> i>2} 
val result2 = list2.filter{i -> i>2}
listOf(1, 2, 3, 4, 5, 6, 7, 8, 9)

是一个包含9个数字的列表——具体来说,是Ints。

然而,1..9是一个范围对象——具体来说,是一个IntRange

listOf(1..9)

是包含单个对象的列表。

list1.filter{ i -> i > 2 }

是有效的,因为filter()将其lambda应用于列表中的每个Int-并且>运算符定义在两个Int之间。

list2.filter{ i -> i > 2 }

无效,因为lambda应用于IntRange,并且您不能将IntRangeInt进行比较。


你的IDE和编译器应该会给你一些提示。首先,如果您将鼠标悬停在list1list2上,您将看到编译器为它们推断的类型:分别是List<Int>List<IntRange>

IDE不仅在{ i -> i > 2 }下面加下划线,还用红色显示>。悬停在上面会显示错误"未解析的引用"。由于收件人类型不匹配,以下候选项都不适用……"这有点晦涩,但你应该了解它,因为它非常常见且非常有用。它告诉你,你正在尝试调用一个函数/方法/操作符,而这个函数/方法/操作符不是为你所拥有的类型定义的。在本例中,为两个Int、两个Long、两个String等定义了>(相当于compareTo()),但为IntRangeInt定义了而不是

所以编译器不知道它应该有什么返回类型,并且暂时假设Unit-但是filter()需要一个返回Boolean的lambda,这就是为什么整个lambda都下划线' type mismatch '错误。


正如Tenfour04所说,如果需要,您可以范围转换为列表(使用toList()方法)。但在实践中,这并不经常需要,因为通常有更好的方法。(范围比大多数列表占用的内存少得多,因此迭代速度更快;而且它实现了Iterable,所以你已经可以用它做大多数列表类型的事情了。

相关内容

最新更新