2017-01-11 4 views
5

私は、Javaslang-2.1.0-alphaとJavaslang-matchと同等のオブジェクト分解を使用しています。 「ファンシー道を一致」のダニエルthis by blog記事によると:Javaslangオブジェクトの分解が機能しない

Match(person).of(Case(Person("Carl", Address($(), $())), (street, number) -> ...)) 

streetnumberAddress内部の2つのワイルドカードパターンに一致する値を取得する必要がありますが、一例であってもコンパイルされません。私は後で、すべてのオブジェクトを原子パターン内にラップする必要があることを認識しました。つまり、「Carl」は$(「Carl」)になります。これはthis issueを読んだ後です。

私はupdated tutorialに従っていますが、この例は更新されていません。

私はこれに例を更新:

Person person = new Person("Carl", new Address("Milkyway", 42)); 

String result2 = Match(person).of(
Case(Person($("Carl"), Address($(),$())), 
     (street, number) -> "Carl lives in " + street + " " + number), 
Case($(),() -> "not found") 
); 
System.out.println(result2); 

それはコンパイルが、私の値はコンソール出力から判断し、適切にマッチされていない:

Carl lives in Carl Address [street=Milkyway, number=42] 

それは明らかだstreetカールが含まれていることnumberAddressオブジェクト全体。

私はカールをキャッチするために第三のラムダパラメータを追加しよう:

Case(Person($("Carl"), Address($(),$())), 
     (name, street, number) -> "Carl lives in " + street + " " + number) 

コードをコンパイルすることはできません、ラムダ式は、次のエラー・テキストを赤い下線を取得します。

The target type of this expression must be a functional interface 

javaslang-matchの最新バージョンで$_の値を無視する方法はありません。だから私は上記のように3つのラムダパラメータを返す原子パターンのそれぞれにマッチしたい。

このライブラリを理解してくれた人には、このオブジェクトを最新のバージョンで分解する方法を私に説明する必要があります。

答えて

7

免責事項:私はJavaslangのクリエイターです。

ケースは(String、Address) - > {...}を処理する必要があります。 $()は任意の値に一致しますが、ハンドラ/関数は分解されたオブジェクトツリーの最初のレイヤだけを受け取ります。 $()は2番目のレイヤーにあります。

ルール:すべてのレイヤーがパターンと照合され、最初のレイヤーのみがハンドラに渡されます。

実際にMatchの最初のプロトタイプは任意のツリー深度を処理しましたが、可能なすべての組み合わせについてフードの下で生成されるメソッドハット - 最大バイトコードサイズは簡単に超過し、コンパイル時間は指数関数的に無限に展開されました。

現行のバージョンのマッチは、現時点でJavaで見られる唯一の実用的な方法です。

更新:

私はこのトピックの詳細比喩更新を与えるせてください。

我々は

  1. 間入力のオブジェクトグラフを区別
  2. 分解オブジェクトのオブジェクトグラフのマッチケースに渡さパターンツリー

広告1)オブジェクトグラフ

オブジェクトが与えられていると、オブジェクトグラフはプロパティを横断することでスパンします。インスタンス変数)。特に、オブジェクトにサイクル(例えば、それ自体を含む変更可能なリスト)が含まれることを禁止していません。

Javaslangには、ナチュラルという方法でオブジェクトを分解する方法があります。そのためには、いわゆるパターンが必要です。オブジェクトグラフの

例:

 Person  <-- root 
    / \ 
"Carl" Address <-- 1st level 
     / \ 
"Milkyway" 42 <-- 2nd level 

広告2)パターンツリー

パターン(インスタンス)は、本質的にオブジェクトを分解する方法を定義します。この例では

パターンの種類は(単純化し、ジェネリック医薬品)のようになります。

 Person(...) 
     / \ 
$("Carl") Address(...) 
      / \ 
      $() $() 

JavaslangのマッチAPIは以下を行います。

Pattern2<Person, String, Address<String, Integer>> 
      /   \ 
Pattern0<String> Pattern2<Address, String, Integer> 
         / \ 
      Pattern0<String>  Pattern0<Integer> 

と呼ばれるパターンの方法は、上記の型のインスタンスを返します。

  1. 一致インスタンスは、Fiに与えpersonオブジェクトを渡し最初のケース。指定されたオブジェクトpersonタイプPersonである場合
  2. ケースパターンPerson(...)
  3. Person(...)パターンチェックにpersonオブジェクトを渡します。次いで
    • trueの場合、パターンは、サブパターン$("Carl")Address(...)一致した場合、その部分 (タプルで表される)、およびチェックにこれらの部品をオブジェクトを分解(再帰的に3を繰り返す)
    • falseの場合、試合
    • パターンがアトミックである場合、つまりオブジェクトをそれ以上分解できない場合は、等価性がチェックされ、呼び出し元に大文字小文字の区別があることが通知されます。
  4. 一致ケースがパターンマッチを得たとき、それがマッチケースハンドラにオブジェクトグラフの最初のレベルの分解対象物を通過します。

現在のJavaの型システムは、私たちは、ハンドラに型指定された方法で任意のオブジェクトグラフ/ツリーレベルの一致するオブジェクトを渡すことはできません。

広告3)分解は)我々はすでに2で上記目的分解を述べた

オブジェクト。特に、与えられたオブジェクトの一部がパターンツリーを送信するときに使用されます。

ので、我々は、上述したタイプのシステムの制限のため、我々は分解部品を取り扱うの方法からオブジェクトをマッチングのプロセスを分離します。

Javaでは、任意のオブジェクトグラフに一致させることができます。私たちはここのどのレベルにも限定されません。

しかし、オブジェクトが正常に一致した場合、最初のレイヤの分解されたオブジェクトのみをハンドラに渡すことができます。

は、私たちの例では、これらの分解のオブジェクトは、与えられたperson(とないstreetnumber)のnameaddressです。


これは、Match APIのユーザーには分かりません。

次のJavaバージョンの1つに、値オブジェクトとネイティブパターンマッチングが含まれます。しかし、そのパターン一致のバージョンは完全に第1レベルに制限されます。

Javaslangは任意のオブジェクトグラフに一致させることができますが、価格はあります。ハンドラは分解されたオブジェクトの最初のレイヤだけを受信しますが、混乱する可能性があります。

これはわかりやすい質問に答えることを希望します。

- ダニエル

+0

私は再エコー私は今理解して何をしてみましょう:私たちは私が達成したいものを達成したい場合は道の物事は、現在、私たちは、人の手の内側Addressオブジェクトを分解し、すべてのアドレスを配置する必要がありますPersonの直下にある属性。これは正しいです?? – egima

+0

@egimaはい、正しいです! (遅い答えに申し訳ありません - 何とか私は通知されませんでした) –

関連する問題