Union types in Java

◇◆丶佛笑我妖孽 提交于 2019-12-23 07:47:09

问题


I've been working with C# for a while and trying to get more familiar with Java. So I'm trying to migrate some of the basic patterns I use on daily basis in C# even only to understand the gap between JVM and dotnet and figure out how to deal with them. Here is the first problem I encountered - an option type - somethiong which is quite easy to achieve in many languages i.e. Koltlin:

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

so I can easily create a map functor:

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))} 

Is this something I can achieve in Java? Im not concerned about the lack of extentions methods, I can leave without that, but how to perform the actual type matching without having to rely on an unchecked cast? At least thats what IntelliJ is complaining about...


回答1:


in the specific case you mentioned, the following would work:

  • (as @oldcurmudgeon mentioned) java.util.Optional it also has a map function.
  • there's also the guava library, that has com.google.common.base.Optional, in case you want it for java version 7 and below. the equivalent of map here would be the transform function.

Java doesn't have pattern matching. The closest you can get to pattern matching in Java is with the visitor pattern.

usage:

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
    }
});

boilerplate 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);
    }
}


来源:https://stackoverflow.com/questions/49491593/union-types-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!