如何循环遍历具有不同数据类型的集合/映射数组

Ric*_*Wit 0 kotlin

我想让我的代码保持干燥并创建 3 个(或更多或更少)具有相同结构的按钮。因此,我创建了一个要循环的对象列表,并将数据放入对象内,以便在 AppButton 中的多个位置使用。

我可能觉得有点太Pythonic了,因为那是我的主要语言,而且我最近才开始使用Kotlin。我通常用Python做的事情:

app_buttons = [
    dict(
        text="....",
        icon="....",
        uri_string="....",
    ),
    ...
]

Run Code Online (Sandbox Code Playgroud)

我在 Kotlin 中尝试过类似的方法mapOf

val appButtons = arrayOf(
    mapOf(
        "title" to getString(R.string.app_btn_example1),
        "icon" to R.drawable.ic_some_icon_1_64,
        "uriString" to "myapp://example1",
    ),
    ...
)
Run Code Online (Sandbox Code Playgroud)

然后循环它们并从地图中获取:

for (entry in appButtons) {
    buttons.add(
        AppButton(
            entry.get("text"),
            entry.get("icon"),
        ) {
            val intent = Intent(Intent.ACTION_VIEW, Uri.parse(entry.get("uriString"))).apply {
                val name = getString(R.string.saved_account_key)
                putExtra(name, sharedPref.getString(name, null))
            }
            startActivity(intent)
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

但后来我明白了Type mismatch. Required String. Found {Comparable & java.io.Serializable}?。我不知道该把什么类型放在哪里......

好的不同的方法,使用setOf和解构:

val appButtons = arrayOf(
    setOf(
        getString(R.string.app_btn_example1),
        R.drawable.ic_some_icon_1_64,
        "myapp://example1",
    ),
    ...
)

for ((text, icon, uriString) in appButtons) {
    buttons.add(
        AppButton(
            text,
            icon
        ) {
            ...
        }
    )
}
Run Code Online (Sandbox Code Playgroud)

但现在我得到以下信息:

Set<{Comparable<*> & java.io.Serialized}> 类型的解构声明初始值设定项必须具有 'component1()' 函数

Set<{Comparable<*> & java.io.Serialized}> 类型的解构声明初始值设定项必须具有 'component2()' 函数

Set<{Comparable<*> & java.io.Serialized}> 类型的解构声明初始值设定项必须具有 'component3()' 函数

我该如何进行这项工作?如何创建基本的对象列表并使用正确的类型循环它们?用Python感觉很简单。我显然错过了一些东西。

Swe*_*per 5

您应该创建一个数据类,而不是使用地图。例如:

data class ButtonModel(
     val title: String,
     val icon: Int,
     val uriString: String,
)
Run Code Online (Sandbox Code Playgroud)

然后您可以像这样创建数组:

val appButtons = arrayOf(
    ButtonModel(
        title = getString(R.string.app_btn_example1),
        icon = R.drawable.ic_some_icon_1_64,
        uriString = "myapp://example1",
    ),
    ...
)
Run Code Online (Sandbox Code Playgroud)

或者如果您愿意,也可以不使用参数标签:

val appButtons = arrayOf(
    ButtonModel(
        getString(R.string.app_btn_example1),
        R.drawable.ic_some_icon_1_64,
        "myapp://example1",
    ),
    ...
)
Run Code Online (Sandbox Code Playgroud)

然后,您可以只使用点语法,而不是使用getor获取它们:[]

buttons.add(
    AppButton(
        entry.text,
        entry.icon,
    ) {
        val intent = Intent(Intent.ACTION_VIEW, Uri.parse(entry.uriString)).apply {
            val name = getString(R.string.saved_account_key)
            putExtra(name, sharedPref.getString(name, null))
        }
        startActivity(intent)
    }
)
Run Code Online (Sandbox Code Playgroud)