I have an Android app written 100% in Kotlin.

In my unit test class I have 2 test observers, one observing integers, another - objects:

val conversationCountObserver: TestObserver<Int>
val conversationObserver: TestObserver<Conversation>

For each one I want to do some basic assertions, like check that there were no errors and check the values observed. I decide to write a generic method that can do a number of assertions on a list of elements in an RX TestObserver class, and 2 proxy methods to pass corresponding observer and vararg of values via Kotlin * spread operator:

private fun thenConversationsNotified(vararg conversations: Conversation) {
    thenTestObserverNotified(conversationObserver, *conversations)
}

private fun thenConversationCountNotified(vararg counts: Int) {
    thenTestObserverNotified(conversationCountObserver, *counts)
}

private fun <T>thenTestObserverNotified(observer: TestObserver<T>, vararg elements: T) {
    observer.assertNoErrors()
    elements.forEachIndexed { index, element ->
        observer.assertValueAt(index, element)
    }
}

thenConversationsNotified() method works just fine, however the thenConversationCountNotified() shows an error:

enter image description here

enter image description here

在阅读Kotlin docs(http://kotlinlang.org/docs/reference/java-interop.html#java-arrays)之后,我意识到原语类型的vararg实际上创建了一个IntArray对象,而不是一个数组,这是作为Java互操作的一个解决方案完成的,它以不同于对象的方式对待原语的vararg.所以我必须重写与你的对话.toTypedArray():

private fun thenConversationCountNotified(vararg counts: Int) {
    thenTestObserverNotified(conversationCountObserver, *counts.toTypedArray())
}

为什么spread运算符对基本数组类的处理方式与对对象数组的处理方式不同?有没有办法取消对的呼叫.这里是toTypedArray()吗?

附注:请注意,在上面的链接中,它们声明intArrayOf(1,2,3)返回IntArray,并且在将其传递给另一个方法时,扩散运算符工作正常.所以扩散运算符确实适用于IntArray类.Kotlin文档中的示例和我的方法之间唯一的区别是,我在一个方法中有两个参数,一个是具体的,一个是vararg.

推荐答案

如果将Int类型用作类型参数(在本例中替换为T),则不能使用JVM原语,这是一个JVM限制(它有一个方法签名,用java.lang.Object代替类型参数,因此它不能接受原语).

vararg使情况变得复杂,但在幕后,接受vararg elements: T的函数与接受Array<T>的函数相同.

因此需要传递Array<Int>(装箱整数数组)而不是IntArray(基元数组),而.toTypedArray()函数是获得前者的方法.

Kotlin相关问答推荐

Kotlin中函数引用的否定

KMP:未能添加cafe.adriel.voyager依赖项

数据流弹性模板失败,出现错误&未知非复合转换urn";

有没有一种简单的方法来识别物体?

如何让 LocalDateTime.parse 拒绝 24:00 时间

Kotlin 协程:flatMapLatest 什么都不发出

在 kotlin 中使具体化字段可选

有什么方法可以要求在 kotlin 中的类型参数上进行注释?

Kotlin 函数有 2 个参数用于对 Map 或 List 进行排序

如何在 jOOQ 中两次加入同一张表?

Kotlin:伴随对象内的函数扩展

如何使用 Hilt 注入应用程序:ViewModel 中的上下文?

Koin Android:org.koin.error.NoBeanDefFoundException

Kotlin 协程中的 Dispatchers.Main 和 Dispatchers.Default 有什么区别?

Kotlin - mutableMapOf() 会保留我输入的顺序

未在IntelliJ IDEA上运行临时文件

在Kotlin中传递并使用函数作为构造函数参数

Android Jetpack导航,另一个主机片段中的主机片段

查找是否在列表中找到具有特定属性值的元素

Android Compose 生产准备好了吗?