1

我正在使用 Danger Detekt(基于 ktlint 的静态代码质量测量系统)。我有一个从 8 个不同端点获取数据的函数。然后我需要检查这些值是否不为空,如果是,我返回使用这些值构建的复杂数据类型,但如果这些值中的任何一个为空,我必须返回空。假设它看起来像这样:

val first = endpoint.get()
...

然后我可以用复杂的 if 语句检查它,但 Detekt 会抱怨复杂的条件。所以我把它改成这样:

val first = endpoint.get() ?: return null
...

但是 Detekt 现在抱怨返回语句太多,因为我必须将它添加到每次提取中。

对于此类问题,是否有任何方便的 Kotlin 功能?

4

1 回答 1

0

您可以使用 fold 来收集 each 的结果,但是一旦您遇到 null 结果,就get制作累加器(并在尝试每次调用之前检查它)。所以它锁定到失败状态:nullget

typealias Result = String

data class Endpoint(val name: String, val result: Result?) {
    fun get(): Result? {
        println("Getting endpoint $name - result is $result")
        return result
    }
}

val endpoint1 = Endpoint("One", "Result 1")
val endpoint2 = Endpoint("Two", null)
val endpoint3 = Endpoint("Three", "Result 3")
val endpoints = listOf(endpoint1, endpoint2, endpoint3)

// I heard yr linter hates returns
fun resultCollector(results: List<Result>?, endpoint: Endpoint) = 
    results?.run {
        endpoint.get()?.let { results.plus(it) }
    }

fun main() {   
    endpoints.fold(emptyList<Result>(), ::resultCollector)
}

>> Getting endpoint One - result is Result 1
   Getting endpoint Two - result is null
   (end)

您可以使用 lambda 而不是函数引用,但我只是想让它清楚 - 您通过文件夹传递一个结果列表,并且该函数执行几个空值检查(检查results列表,检查get调用结果)。这两个检查都可以评估为 null,这就是函数将作为下一个累加器返回的内容 -Result如果您没有遇到 null,则仅执行端点代码(并且实际返回)

就我个人而言,我认为这种解释意味着也许只有几个早期的回报更容易理解,而且当它们排成一列时可能看起来更整洁。不过由你决定!

于 2021-01-27T16:59:47.470 回答