2017-02-01 11 views
1

Data1とData2のインスタンスが異なる能力を持つという説明は何ですか?コンストラクタを持つクラスのための異なる能力

Data1クラスのオブジェクトがインスタンス化される行は問題なくコンパイルされますが、Data2の行はという右側のサブタイプである必要があります。というエラーが表示されます。ポニーに

class Data1 
    let _x: U8 = 0 

class Data2 
    let _x: U8 
    new create() => _x = 0 

actor Main 
    new create(env: Env) => 
    let d1: Data1 iso = Data1 
    let d2: Data2 iso = Data2 

答えて

3

、あなたは構文または構造の基本的な要素を省略し、それらは暗黙のデフォルト値で満たされることを期待することができます多くの場所があります。 Data1Data2の違いについての質問に対する答えは、同じ機能を持たない暗黙のデフォルトの2つの例と関係しています。

Data2クラスには、new create() => _x = 0という単一のコンストラクタがあり、暗黙的なデフォルトの受信者機能はrefです。つまり、暗黙的にnew ref create() => _x = 0に展開されます。

Data1クラスにはコンストラクタがありません。したがって、Ponyは暗黙的なデフォルトコンストラクタを作成します。これはnew iso create()です。フィールド宣言の_x = 0も暗黙的にコンストラクタの本体に転送されますが、それはあなたの質問の範囲外です。作成されたオブジェクトは、Data1 isoに割り当てることができるタイプData1 iso^、であろうため


したがって、この場合には、let d1: Data1 iso = Data1を割り当てます。代入保証を解除することなくData2 isoに割り当てることはできません。の割り当ては作成されたオブジェクトのタイプがData2 ref^であるため機能しません。

Data2コンストラクタをnew iso create()に変更することは、サンプルコードを作成するための最良のソリューションです。コンストラクタの暗黙の既定の機能としてisoを使用しません。コンストラクタへのパラメータに追加の制約を課すためです(すべて送信可能でなければならない)。


完全性のために、発信者側に別の方法があることに注意してください。 recoverブロックにコンストラクタコールを配置すると、保証がより強い機能に「持ち上げる」ことができます(たとえば、refからisoまで)。これは、recoverブロックが、その中で使用されているオブジェクト参照(たとえば、リカバリブロックに渡されるすべての参照が送信可能でなければならないなど)に他の制約を強制し、解除する保証を維持するためです。この割り当ては次のようになります。

let d2: Data2 iso = recover Data2 end 
+0

非常に詳細な回答はありがとうございます。私はそのようなものを期待していました。デフォルトのコンストラクタの場合は、デフォルトが異なります。 最初の解決策は間違いなく良く見えます。私は自分自身で見つけたが、そうすることは慣習的であるかどうかは分かりませんでした。 – aav

関連する問題