このコードスニペットに関連してわからない動作が発生しています。より正確には、演算子がタイプProjection
の場合(すなわち、n.isProjection()
が真の場合)、private double getUniqueCost(final Node p)
というシグニチャを持つメソッドではなく、private double getUniqueCost(final Projection p)
というシグニチャを持つメソッドを呼び出すことが、getUniqueCost
メソッドの呼び出しを予期していました。オーバーロードの混乱する動作
ProjectionはNodeのサブクラスであることに注意してください。
ここでは、2つの前述の方法のためのコード:実際に第二メソッドを呼び出すために管理するための唯一の方法は、次のように最初の方法を変更することであった
private double getUniqueCost(final Node n){
if(n.isScan())
return getUniqueCost(estimateCardinality(n));
if(n.isJoin())
return getUniqueCost((NJoin) n);
if(n.isUnion())
return getUniqueCost((Union) n);
if(n.isMaterialization())
return getUniqueCost(n.getChildren().iterator().next());
if(n.isProjection()){
return getUniqueCost(child.isJoin() ?
n.getChildren().iterator().next() : ((Projection) n));
}
throw new IllegalArgumentException("Unknown node type: " + n.getOperator());
}
private double getUniqueCost(final Projection p){
return getUniqueCost(estimateCardinality(p)) +
getUniqueCost(p.getChildren().iterator().next());
}
(省略符号は前と同じです)。
(つまり、パラメータがメソッド自体を評価する前に評価されている値のセマンティクスによって呼び出す)、私はほとんどを呼び出すのに十分であることを期待していたキャストが実際にメソッドを呼び出す前に実行されることを考えるとprivate double getUniqueCost(final Node n){
[...]
if(n.isProjection()){
final Node child = n.getChildren().iterator().next();
if(child.isJoin()){
return getUniqueCost(child);
}
final Projection proj = (Projection) n;
return getUniqueCost(proj);
}
throw new IllegalArgumentException("Unknown node type: " + n.getOperator());
}
具体的な方法(on例えば、Projection
のパラメータを受け入れます。私は、Javaの型システムを見ていたので、それがしばらくされている
、私の容疑者は、式全体child.isJoin() ? n.getChildren().iterator().next() : ((Projection) n)
が、左サイドの部分にそれらのタイプは確かにNode
で、Node
として入力されていることです。
誰でも確認できますか?いいえ、ここで起こっていることをよりよく理解していますか?
さらに、コードの2番目のバージョンを書くために、よりコンパクトな(エレガントな)方法があるのでしょうか?
これは私が式の静的型付けに念頭に置いていたものですが、実行時に動的な型定義が少し洗練され、どの「分岐」が取られるかを知っていると思いました。どうやら私はあまりにも多くを期待していた。もう一つのヒントもありがとうございます。 –