我正在尝试通过其属性之一(即字符串资源ID)来标识对象。但是,从对象读取的字符串资源标识符与直接查找的字符串资源标识符的值不同。
// A data class with one property being a string resource ID
data class Foo(labelResId: Int, ...)
// An instance of Foo is created as a class property
private val foo = Foo(labelResId = R.string.my_string)
// I attempt to look up this specific object in a collection things
things.find { it is Foo && it.labelResId == R.string.my_string } // Fails to find foo
最后一行未能找到我的对象,因为it.labelResId
和R.string.my_string
返回的值即使最初都引用R.string.my_string
也不同。但是,在将资源与标签资源ID进行比较之前将其分配给值会导致成功查找。
val targetResId = R.string.my_string
things.find { it is Foo && it.labelResId == targetRedId } // Successfully finds foo
以R.string.my_string
的形式查找时,资源ID为 -1901331 。在编译时分配给值时,资源ID为 2131887532 。到目前为止,我已经能够理解这两个数字之间的相关性,即max int以及Android如何在编译期间将R.string中的资源ID从R.string分配给R.java中的值,但是我不明白为什么内联{{1 }}也不会转换为正ID。
编辑1:这是我的代码的屏幕截图,以供澄清。对于上下文,此代码正在讨论RecyclerView中的“用户类型”下拉列表。
调试时的断点显示R.string.user_type的评估值(弹出评估气泡)与使用R.string.user_type构造时分配给FormDropdownRow :: labelResId的值不同(图片的右侧)
现在,即使在构造FormDropdownRow的实例中将R.string.my_string
设置为R.string.user_type时,该断点现在仍显示对“ when”条件的评估为假。位置19的项目是item.labelResId
中FormDropdownRow的唯一实例;我不是偶然地比较了两个不同的项目。
编辑2:我开始认为此运行时错误与listItems
的运行方式有关。例如,此代码无法分配正确的视图类型。
when
但是,此代码成功。
... = when (item = listItems[position]) {
item is FormDropdownRow && item.labelResId == R.string.user_type -> USER_TYPE
...
}
此代码还可以成功分配正确的视图类型。
... = when (item = listItems[position]) {
is FormDropdownRow -> if (item.labelResId == R.string.user_type) USER_TYPE else throw Exception()
...
}
我很困惑,因为上面的第一种情况和第三种情况对我来说都是相同的,尤其是因为IntelliJ建议用when块代替级联的if语句。