Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin中的动态属性访问_Kotlin - Fatal编程技术网

Kotlin中的动态属性访问

Kotlin中的动态属性访问,kotlin,Kotlin,在Kotlin基础课程中,我们有以下代码: @绑定适配器休眠 有趣的ImageView.setSleepImageitem:SleepNight?{ 项目?让我们{ setImageResourcewhen item.sleepQuality{ 0->R.drawable.ic\u sleep\u 0 1->R.drawable.ic\u sleep\u 1 2->R.drawable.ic\u sleep\u 2 3->R.drawable.ic\u sleep\u 3 4->R.drawab

在Kotlin基础课程中,我们有以下代码:

@绑定适配器休眠 有趣的ImageView.setSleepImageitem:SleepNight?{ 项目?让我们{ setImageResourcewhen item.sleepQuality{ 0->R.drawable.ic\u sleep\u 0 1->R.drawable.ic\u sleep\u 1 2->R.drawable.ic\u sleep\u 2 3->R.drawable.ic\u sleep\u 3 4->R.drawable.ic\u sleep\u 4 5->R.drawable.ic\u sleep\u 5 else->R.drawable.ic\u sleep\u active } } } 在其他语言中,我会通过使用sleepQuality整数查找匹配元素来简化此过程,例如在Typescript中:

setImageResourceR.drawable[`ic\u sleep\u${item.sleepQuality}`]??R.drawable.ic\u sleep\u active 要开始尝试,即使我的第一步没有编译:

0 -> R.drawable["ic_sleep_0"] // doesn't compile
这种手术在科特林可行吗

编辑/更新 这里有一些很好的回应

对于这个特定的用例,我可以按字符串查找资源,类似于我正在尝试的:

val resId = context.resources.getIdentifier("ic_sleep_${item.sleepQuality}", "drawable", context.packageName)
然而,这不是一个普遍的解决办法。以下操作不起作用:

val x = item['sleepQuality']
正如在一些回复中所指出的,这可能是通过反射实现的。如何做到这一点

val resId = context.resources.getIdentifier("ic_sleep_${item.sleepQuality}", "drawable", context.packageName)
setImageResource(if (resId != 0) resId else R.drawable.ic_sleep_active)
通过基于以下内容的思考:


只使用反射。Kotlin是一种静态类型的编程语言,不支持变量

Hi,有趣,可能使用我不知道您在这里使用的对象,但是有没有一种方法可以使用数组或列表(为索引访问而设计的类型),而不是一系列单独的属性?@gidds是的,这个示例中,被编号,作为一个数组会更好吗?你能拥有一个资源数组吗?但总的来说,我的问题仍然存在。我不确定代码来自何处,也不确定它是否是为了展示一个开关而编写的,但我只想指出,只使用固定的LevelListDrawable并修改其级别会更干净。使用反射或getIdentifier by string的解决方案不提供编译时安全性,因此通常应避免使用这些解决方案。resources.getIdentifier在后台使用反射。请注意,应该避免使用反射,因为它丢掉了使用强类型语言的好处—编译器在您运行代码之前捕获您的错误。如果您首先将可绘图项存储在数组中,您就不需要这个when语句。还值得指出的是,反射虽然看起来很吸引人,但对于Kotlin这样的静态类型语言中的通用编程来说,反射很少是一个好的解决方案。当然,在编写框架、插件、测试、编译时工具、依赖注入等等时,它是必要的,也是非常有用的。但是它绕过了类型系统和所有通常的编译时检查和优化,性能很差。如果您发现自己正在努力实现它,这通常意味着有更好的方法来构建代码。
val resId = try {
    R.string::class.java.getField("ic_sleep_${item.sleepQuality}").getInt(null)
} catch (e: Exception) {
    R.string.ic_sleep_active
}
setImageResource(resId)