关于 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
一样使用 mapOf
,mapOf("a" to arrayOf(...
了解您一般需要注意的事项。 lateinit
可能真的很有用,但你需要知道自己在做什么!
精简到最本质,我的问题是:
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
一样使用 mapOf
,mapOf("a" to arrayOf(...
了解您一般需要注意的事项。 lateinit
可能真的很有用,但你需要知道自己在做什么!