java - 如何在 Kotlin 中创建一个空的不可变的“类型安全”集合?
问题描述
我在 Java 和现在的 Kotlin 中策划了一些不可变的集合。我经常创建一个空的不可变集合的单例实例,因为 Java 具有类型擦除,并且该实例是相同的并且可以安全地为所有集合共享。
在 Java 中,您可以创建一个非泛型单例对象并将其包装在一个函数中,以便在从泛型类型安全代码调用时让类型推断适用于任何类型。我从java.util.Collections 类中采用了这种技术:
// v-No generic types specified-v
public static final List EMPTY_LIST = new Collections.EmptyList();
// v-------v-- generic type "passes through"
public static final <T> List<T> emptyList() {
return EMPTY_LIST;
}
所以这是我自己的 Java 代码,应该看起来非常相似(并且有效):
public static final Xform EMPTY = new SourceProviderIterableDesc<>(Collections.emptyList());
@SuppressWarnings("unchecked")
public static <T> Xform<T> empty() {
return (Xform<T>) EMPTY;
}
在这里它被转换为 Kotlin:
private val EMPTY: Xform<Nothing> = SourceProviderIterableDesc(emptyList())
@Suppress("UNCHECKED_CAST")
internal fun <T> empty(): Xform<T> =
EMPTY as Xform<T>
我得到这个错误:
java.lang.ExceptionInInitializerError
at org.organicdesign.fp.xform.XformTest.construction(XformTest.kt:529)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: kotlin.TypeCastException: null cannot be cast to non-null type org.organicdesign.fp.xform.Xform<T>
如何在 Kotlin 中使用 add-a-type-to-something-with-no-type 技巧?另外,这个有名字吗?
注意:如果我在 Kotlin 中使用listOf()
而不是,我会得到同样的错误。emptyList()
解决方案
推荐阅读
- rest - 如何在 Swagger UI 中的数组查询参数中提供值
- paypal - Worldpay PayPal 错误:BAD_REQUEST,未指定所需 URL 且未定义默认值
- php - 单个列过滤(选择输入)可变
- android - 如何在 C# 上使用预览为 android 创建 PDF 查看器
- python - 检查数字是否在给定范围内:未能按指示打印消息
- r - 不是散点图中的所有值
- html - 在另一个组件Angular 7中绑定ngModel上的值
- facebook-graph-api - 如何以编程方式在 DNN 标头标签中包含元标签?
- python - 如何使用 PyLucene 从所有索引文档中检索特定字段?
- http - 如何将 http 服务调用返回的值绑定到 Angular6 中 UI 中的字段下拉列表