0
class StuffContainer(var stuff: MutableList<String>?) {
    fun appendSomeStuff(newStuff: List<String>) { // Appends to stuff, initialising it if null
        stuff?.addAll(newStuff) ?: let { stuff = ArrayList<String>(newStuff) }
    }
}

fun main (args: Array<String>) {
    val container = StuffContainer(null)

    val arr : ArrayList<String> = ArrayList()
    arr.add("abc")
    arr.add("bcd")

    // Now I want to put arr in container
    container.appendSomeStuff(arr)
    println(container.stuff) // [abc, bcd]

    // That worked. Now how to implement the logic in StuffContainer.appendSomeStuff here?
    container.stuff = null
    //container.stuff?.addAll(arr) ?: let { container.stuff = ArrayList<String>(arr) }
    // Can't write a let expression here

    if (container.stuff == null) {
        container.stuff = ArrayList<String>(arr)
    } else {
        container.stuff?.addAll(arr)
    }
    println(container.stuff) // [abc, bcd]
}

这是我拥有的代码的精简版本。在上面的代码中,我编写了一个 main 以便可以复制和执行它。但在实际使用中,我有一个函数,它获取一个“StuffContainer”对象作为参数。

我无法弄清楚如何在该类之外定义的函数中正确处理类中字段的空值。我不能使用 let 表达式,所以我使用的是 if-else 块。

这是最好的方法吗?尽管所有 kotlin 都试图避免由于从某个地方将 vars 设置为 null 而导致的错误,但当在 if 块的 null 检查之后将“container”设置为 null时,此代码将无法正常工作。有没有更好的办法?

4

1 回答 1

0

TLDR

你想做这样的事情。

 when {
        container.stuff == null -> container.stuff = ArrayList<String>(arr)
        else -> container.stuff?.addAll(arr)
    }

或者

 container.stuff = container.stuff ?: ArrayList(arr)

可能有更好的方法来做到这一点。

说明

你期望使用这样的东西

container.stuff?.addAll(arr) ?: let { container.stuff = ArrayList<String>(arr) }

我做错了什么?

首先,您当前使用该let方法的方式似乎有些错误。该let函数在特定数据项上调用,其中计算的表达式被传递给 lambda。

仅当表达式的计算结果为 NOT null 时才调用该函数。

为什么是错的?

  • let 函数不是这样调用的

这行得通吗?

container.stuff?.addAll(arr)?.let { container.stuff = ArrayList<String>(arr) }

这也不起作用,因为你的container.stuff为空,所以addAll不会调用该函数,因此它不会进入let块。

于 2018-02-07T07:04:33.637 回答