简体   繁体   English

菜鸟Kotlin on Android MutableMap初始化问题

[英]Newbie Kotlin on Android MutableMap initialisation question

Stripped down to the bare essence, my problem is:剥离本质,我的问题是:

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"))

    }
}

Why do I get this error for testMap...为什么我的 testMap 会出现此错误...

lateinit property testMap has not been initialized lateinit 属性 testMap 尚未初始化

...but no error for testArray? ...但是 testArray 没有错误?

Edit for improved question quality: I understand that lateinit variables must be initialised later, before they are used - but isn't that what I am doing?编辑以提高问题质量:我知道 lateinit 变量必须稍后在使用之前初始化 - 但这不是我在做什么吗? It seems to work with testArray , but not with testMap .它似乎适用于testArray ,但不适用于testMap Why are they different?他们为什么不同?

Edit 2: This variation...编辑 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")))

...works. ...作品。

I don't know if you got what's happening here, but just in case我不知道你是否知道这里发生了什么,但以防万一

Usually when you create a field (a top-level variable, not inside a function or anything), you have to initialise it with a value:通常当你创建一个字段(一个顶级变量,不在 function 或任何东西中)时,你必须用一个值初始化它:

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

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

But sometimes you want to define that variable, but you don't actually have the thing you want to assign to it yet (very common in Android, when the actual setup for Activities and Fragments happens in lifecycle callbacks, long after the object was constructed).但有时你想定义那个变量,但你实际上还没有你想要分配给它的东西(在 Android 中很常见,当活动和片段的实际设置发生在生命周期回调中时,在构造 object 很久之后). You want to init ialise it, late r. That's what lateinit is for你想初始化它,r。这就是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"
}

So lateinit is you promising to initialise that variable before anything tries to access it.所以lateinit是你承诺在任何尝试访问它之前初始化该变量。 The compiler is trusting you to take care of it.编译器相信你会处理好它。

But did you?但是你呢?

// 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"))
    }

So you haven't actually assigned a map to that variable yet - there's nothing there to add values to.所以您实际上还没有为该变量分配 map - 没有任何东西可以添加值。 Normally you'd get warned/prevented from doing this kind of thing, but lateinit allows you to take control, tell the compiler "don't worry, I got this" and safely initialise something later without having to make it nullable.通常你会被警告/阻止做这种事情,但lateinit允许你控制,告诉编译器“别担心,我知道了”并在以后安全地初始化一些东西而不必使它可以为空。 But you have the responsibility to make sure it will always be initialised before it's accessed但是您有责任确保它在访问之前始终被初始化

It's an easy enough fix here - just make a map, you can use mapOf the same way you're using arrayOf if you like, mapOf("a" to arrayOf(... But it's good to know what you need to be aware of in general. lateinit can be really useful, but you need to know what you're doing!这是一个很简单的修复 - 只需制作一个 map,如果您愿意,您可以像使用mapOf一样使用arrayOf ,mapOf mapOf("a" to arrayOf(...但最好知道您需要注意什么一般来说, lateinit可能真的很有用,但你需要知道你在做什么!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM