kotlin - 这些在 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)
是一个由九个数字组成的列表——具体来说,Int
s。
然而,1..9
是一个范围对象——特别是一个IntRange
. 所以:
listOf(1..9)
是一个包含单个对象的列表。
list1.filter{ i -> i > 2 }
是有效的,因为filter()
将它的 lambda 应用到Int
列表中的每个 - 并且>
运算符定义在两个Int
s 之间。然而:
list2.filter{ i -> i > 2 }
无效,因为 lambda 应用于IntRange
,并且您无法将 anIntRange
与 an进行比较Int
。
你的 IDE 和编译器应该给你一些关于这个的线索。首先,如果您将鼠标悬停在上面list1
,list2
您将看到编译器为它们推断的类型:List<Int>
和List<IntRange>
,分别。
IDE 不仅下划线{ i -> i > 2 }
,它还显示>
红色。将鼠标悬停在上面会显示错误“未解决的参考”。由于接收器类型不匹配,以下候选均不适用……' 这有点神秘,但您应该了解它,因为它很常见且非常有用。它告诉您您正在尝试调用未为您拥有的类型定义的函数/方法/运算符。在这种情况下,>
(相当于compareTo()
)是为两个Int
s、两个Long
s、两个String
s 等定义的,但不是为 anIntRange
和 an定义的Int
。
所以编译器不知道它应该有什么返回类型,并暂时假设Unit
——但filter()
需要一个返回 a 的 lambda Boolean
,这就是为什么整个 lambda 带有“类型不匹配”错误下划线的原因。
正如 Tenfour04 所说,如果需要(使用方法) ,您可以将范围转换为列表。toList()
但在实践中,这并不经常需要,因为通常有更好的方法。(范围比大多数列表占用的内存少得多,因此迭代速度更快;并且它实现Iterable
了,所以无论如何你已经可以用它做大多数列表类型的事情了。)
推荐阅读
- docker - Jenkins docker容器无法将war文件部署到tomcat docker容器
- php - 如何缩短此代码,我对每个代码都做同样的事情并声明变量
- subprocess - 使用 python 子进程使用 ssh 登录到远程网络设备
- java - 如何通过按下按钮取消选中并保存复选框的状态
- javascript - 使用 loadVideoById() 函数自动播放 youtube 视频不起作用
- reactjs - “AxiosResponse”类型上不存在属性“blob”
' - delphi - “GetItCmd”任务意外失败 - NullReferenceException
- html - 牌之间的横杠如闪电
- logging - 使用 NLog.Web.AspNetCore 属性(${aspnet-user-identity}、${aspnet-request-url} 等)使用 ServiceStack 配置 Nlog
- javascript - 反应原生:还有另一种方法,如 groupBy 只能过滤 uniq?