我想知道在映射或过滤时如何跳过一项?
fun getFilteredList(list: List<String>, match: String): List<String>? {
val flist = list.filter {
try {
// Some parsing logic which can throw exceptions
val res = SomeParser.parse(match)
it == res
} catch (e: Exception){
// I want to skip this entry to include in flist but still continue
// for left of the list entries without return. How to do that?
return null
}
}
return flist
}
答案 0 :(得分:1)
问题是您使用了return
关键字。您的代码应如下所示:
// return type no longer needs to be nullable
fun getFilteredList(list: List<String>, match: String): List<String> {
val flist = list.filter {
try {
val res = SomeParser.parse(match)
it == res
} catch (e: Exception){
true
}
}
return flist
}
或者,根据您的示例,仅(使用"single-expression function" syntax):
fun getFilteredList(list: List<String>, match: String) = list.filter {
try {
it == SomeParser.parse(match)
} catch (ex: Exception) {
true
}
}
注意:这两个都将为列表中的每个元素调用SomeParser.parse
。但是,您提到的只是一个示例,实际代码的工作方式有所不同(即无法从过滤器操作中退出)。
return
给您错误的原因与lambda表达式有关。在Kotlin参考资料的Returning a value from a lambda expression部分中:
我们可以使用qualified return语法从lambda显式返回一个值。否则,将隐式返回最后一个表达式的值。
因此,以下两个片段是等效的:
ints.filter { val shouldFilter = it > 0 shouldFilter } ints.filter { val shouldFilter = it > 0 return@filter shouldFilter }
[...]
这与事实filter
is an inline
function结合在一起。在Kotlin参考资料的Non-local retuns部分中:
在Kotlin中,我们只能使用普通的不合格
return
退出命名函数或匿名函数。这意味着要退出lambda,我们必须使用label,并且在lambda内禁止使用裸露的return
,因为lambda无法使封闭函数返回:fun foo() { ordinaryFunction { return // ERROR: cannot make `foo` return here } }
但是如果将lambda传递给的函数是内联的,则返回值也可以内联,因此允许:
fun foo() { inlined { return // OK: the lambda is inlined } }
此类返回(位于lambda中,但退出封闭函数)称为非本地返回。 [...]
这意味着当您拥有return null
时,它实际上是在尝试退出整个getFilteredList
函数。我假设这就是为什么您将返回类型设为List<String>?
而不是List<String>
的原因。当您尝试return false
时,您试图从返回类型为Boolean
的函数中返回List<String>?
。