关于 Android MutableMap 初始化问题的新手 Kotlin

Newbie Kotlin on Android MutableMap initialisation question

精简到最本质,我的问题是:

class MainActivity : AppCompatActivity() {

    lateinit var testArray: Array<String>
    lateinit var testMap: MutableMap<String, Array<Array<String>>>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        testArray = arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")
        testMap["a"] = arrayOf(
            arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"),
            arrayOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"))

    }
}

为什么我的 testMap 会出现这个错误...

lateinit property testMap has not been initialized

...但 testArray 没有错误?

编辑以提高问题质量: 我知道 lateinit 变量必须稍后在使用之前初始化 - 但这不是我在做什么吗?它似乎适用于 testArray,但不适用于 testMap。他们为什么不同?

编辑 2:这个变体...

testMap = mutableMapOf("a" to arrayOf(
    arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"),
    arrayOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")))

...有效。

我不知道你是否了解这里发生的事情,但以防万一

通常当你创建一个字段(一个 top-level 变量,不在函数或任何东西内部)时,你必须用一个值初始化它:

// needs to be initialised to something!
val coolString1: String

// now we're going places
val coolString2: String = "ok here"

但有时您想要定义该变量,但您实际上还没有想要分配给它的东西(在 Android 中很常见,当 Activities 和 Fragments 的实际设置发生在生命周期回调,在构造对象很久之后)。你想 init 初始化它,later。这就是 lateinit

的意义
// has to be a var - and look, you're not assigning a value, and it's fine!
lateinit var coolString: String

fun calledLater() {
    coolString = "sup"
}

所以 lateinit 您是否承诺在 任何尝试访问它之前 初始化该变量。编译器相信您会处理它。

但是你做到了吗?

// no array assigned! Will init later
lateinit var testArray: Array<String>
// no map assigned! Will init later
lateinit var testMap: MutableMap<String, Array<Array<String>>>

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // assigning that array you promised to! perfect
        testArray = arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")

        // trying to add something to a map that hasn't been created yet!
        // you're accessing it before it's been assigned, you broke your promise
        testMap["a"] = arrayOf(
            arrayOf("0", "1", "2", "3", "4", "5", "6", "7", "8", "9"),
            arrayOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"))
    }

所以您实际上还没有为该变量分配映射 - 没有任何东西可以添加值。通常你会从做这种事情中得到 warned/prevented,但是 lateinit 允许你控制,告诉编译器“别担心,我知道了”并且稍后安全地初始化一些东西而不必使其可为空。但是您有责任确保它在被访问之前总是被初始化

这里的修复很简单 - 只需制作一张地图,如果您愿意,您可以像使用 arrayOf 一样使用 mapOfmapOf("a" to arrayOf(...了解您一般需要注意的事项。 lateinit 可能真的很有用,但你需要知道自己在做什么!