私はしばらくC#で作業しており、Javaに慣れるために努力しています。したがって、JVMとdotnetの間のギャップを理解し、それらの処理方法を理解するためだけに、C#で日常的に使用するいくつかの基本パターンを移行しようとしています。これが私が遭遇した最初の問題です-オプションタイプ-多くの言語で達成するのが非常に簡単なサムチオング、つまりコルトリン:
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.util.Optional
a map
function もあります。com.google.common.base.Optional
、Javaバージョン7以前で必要な場合。ここではmap
と同等です the transform
関数 。Javaにはパターンマッチングがありません。 Javaは ビジターパターン でパターンマッチングに到達できる最も近いものです。
使用法:
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);
}
}