Kotlin-如何在映射和过滤时跳过关于异常的条目

时间:2019-06-20 05:09:19

标签: android kotlin filter iteration mapping

我想知道在映射或过滤时如何跳过一项?

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
}

1 个答案:

答案 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>?