乍一看,使用 js 中的 kotlin 集合似乎很容易。因为 kotlin multiplatform 及其库(kotlinx.collections 等)生成了 js 和 kotlin 之间可互操作的共享库。 如果我们从 javascript 代码调用 new ArrayList() ,它将构造一个可与 kotlin 多平台代码互操作的 MutableList,但由于损坏,此 mutableList 将无法直接在 js 代码中使用。 事实上,当从 js 创建 mutableList 时,它确实会生成这种对象(mutablelist)
let mutableList = new kt.kotlin.collections.ArrayList(["first", "second", "third"]);
console.log("js mutable list: ", mutableList);
正如你所看到的,所有属性都有损坏(hd7ov6$_0),遗憾的是没有吸气剂。 (由于 @JsName("name") 生成了具有良好名称的 Getters/Setter,这似乎是避免破坏属性和函数名称的唯一方法。
所以我问社区和 kotlin 团队,MPP 上怎么还会出现这样的损坏?感谢 IR 编译器和允许接口和 enum js 导出的新 1.6.20 版本,它会改变吗?
另外,有什么好的解决方法吗?我唯一看到的就是可悲的是基于ArrayList重新实现一个MutableList,但是ArrayList组成的数组是私有的。由于某些 ArrayList 实现方法丢失了私有数组引用,我无法在基类上拥有引用数组。
希望有人可以帮助找到适当的方法来避免这种损坏...... 谢谢;)
可以通过创建包装方法并像普通函数一样导出它们来使用此类方法。
package stdlib
import kotlin.js.JsExport
@JsExport
fun <T>listOf(elements: Array<T>): List<T> = elements.toList()
@JsExport
fun <T>setOf(elements: Array<T>): Set<T> = elements.toSet()
成为
export declare namespace stdlib {
function listOf<T>(elements: Array<T>): kotlin.collections.KtList<T>;
function setOf<T>(elements: Array<T>): kotlin.collections.KtSet<T>;
}
并且可以像这样使用
import {stdlib} from "your-generated-package";
const kotlinList = stdlib.listOf([ "your", "js", "array" ]);
为了实现最大程度的类型安全,我还建议至少升级到 kotlin 的“2.0.0-Beta4”,因为这也会为集合生成正确的类型,而不仅仅是
any
。