【问题标题】:Union types in JavaJava中的联合类型
【发布时间】:2018-09-04 14:32:12
【问题描述】:

我使用 C# 已经有一段时间了,并试图更加熟悉 Java。因此,我尝试迁移我在 C# 中每天使用的一些基本模式,甚至只是为了了解 JVM 和 dotnet 之间的差距并弄清楚如何处理它们。这是我遇到的第一个问题 - 一个选项类型 - 在许多语言中很容易实现的东西,例如 Koltlin:

sealed class Option<out T : Any> {
    object None : Option<Nothing>()
    data class Some<out T : Any>(val value: T) : Option<T>()}

这样我就可以轻松创建地图函子了:

fun <T : Any, B : Any> Option<T>.map(f: (T) -> B): Option<B> =
    when (this) {
        is Option.None -> Option.None
        is Option.Some -> Option.Some(f(this.value))} 

这是我可以用 Java 实现的吗?我不担心缺少扩展方法,我可以不用它,但是如何执行实际的类型匹配而不必依赖未经检查的强制转换?至少这就是 IntelliJ 所抱怨的......

【问题讨论】:

  • 您在询问 Java,但没有显示 Java 代码。我觉得这不对。
  • C# 和 Java 都没有联合类型,任何变通方法充其量都很难使用。对于确实具有联合类型的 .NET 语言,请查看 F#。
  • 看起来您可能正在寻找来自 Java 8 的 java.util.Optional
  • 没有任何完全等价的东西 - 但是为什么你需要一个 Java 解决方案,当你在 Kotlin 中已经有了一个可以完美运行互操作的 Java 解决方案?
  • @OldCurmudgeon,我似乎 java.util.Optional 应该在 Option/Maybe 类型的情况下完成这项工作。感谢您的建议。

标签: java c# kotlin discriminated-union


【解决方案1】:

在您提到的特定情况下,以下方法可行:

Java 没有模式匹配。在 Java 中最接近模式匹配的是 the visitor pattern

用法:

UnionType unionType = new TypeA();

Integer count = unionType.when(new UnionType.Cases<Integer>() {
    @Override
    public Integer is(TypeA typeA) {
        // TypeA-specific handling code
    }

    @Override
    public Integer is(TypeB typeB) {
        // TypeB-specific handling code
    }
});

样板代码:

interface UnionType {
    <R> R when(Cases<R> c);

    interface Cases<R> {
        R is(TypeA typeA);

        R is(TypeB typeB);
    }
}

class TypeA implements UnionType {

    // ... TypeA-specific code ...

    @Override
    public <R> R when(Cases<R> cases) {
        return cases.is(this);
    }
}

class TypeB implements UnionType {

    // ... TypeB-specific code ...

    @Override
    public <R> R when(Cases<R> cases) {
        return cases.is(this);
    }
}

【讨论】:

  • 与某些句法联合类型支持相比,让我觉得难以阅读和推理。
  • @dlamblin,我同意。不久前,当 Java 没有本地联合类型支持时,我写了这个。我不确定 Java 现在是否支持联合类型
  • 我想知道,好像还没有。
猜你喜欢
  • 2018-07-29
  • 1970-01-01
  • 2020-09-22
  • 2022-07-22
  • 2020-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-12
相关资源
最近更新 更多