2013-08-06 9 views
12

パス依存のタイプが便利です:依存型はコンストラクタでは機能しませんか?

trait Sys { 
    type Global 
} 
def foo[S <: Sys](system: S)(global: system.Global) =() 

しないのはなぜコンストラクタのために、この作品?

class Foo[S <: Sys](val system: S)(val global: system.Global) 

これは間違っているのですか?

+0

私はこの文をSLSで見つけました:*正式な値パラメータは、*正式なクラステンプレートt *(5.3、p56)の親クラスまたはメンバの型の一部にはならないかもしれません。プライマリコンストラクタの* valueパラメータ句*。 – Beryllium

+4

回避方法: 'trait Foo [S: senia

+0

@seniaはい、私は今、形質を使用していますが、コンストラクタメソッドはかなり醜いですが、動作します。 –

答えて

5

これは私のバグのようです。 を編集:見つかりました。これはSI-5712です。 2.9 SLSの

節§5.3は言う:

(PS1)。 。 。 (psn)はクラスのプライマリコンストラクタ の正式な値パラメータ句です。正式な値パラメータの範囲には、後続のすべてのパラメータセクションとテンプレートtが含まれます。

は例外があります:

しかし、正式な値パラメータ は、親クラスまたは クラステンプレートTのメンバーのいずれかの種類の一部を形成しない場合があります。

しかし、それはない、次のパラメータセクションのいずれかの、親クラスやメンバーのいずれかの種類の一部にすることはできませんと言うので、それは間のパス依存型を禁じるように思われません引数グループ。あなたが二コンストラクタでこれを一周することができます

class Foo[S <: Sys] private[this]() { 
    def this(system: S)(global: system.Global) = this 
} 

編集:この二コンストラクタ回避策は非常に良いではありません。systemまたは非常に困難になるglobalを露出させ、プライマリコンストラクタはval Sを宣言することができますので、 。

キャストで例:

class Foo[S <: Sys] private[this]() { 
    private[this] var _system: S = _ 
    private[this] var _global: system.Global = _ 

    def this(system0: S)(global0: system0.Global) = { 
    this 
    _system = system0 
    _global = global0.asInstanceOf[system.Global] 
    } 

    lazy val global: system.Global = _global 
    lazy val system: S = _system 
} 

しかし、これはひどいなっています。 @セニアの提案ははるかに良いです。

+0

しかし、二次コンストラクタの問題は、このようにして 'def global:system.Global'を持つ' Foo'を構築することができなくなることです(私は試していませんが、不可能です) –

+0

Hum、あなた'Foo'がこれらの値を公開する簡単な方法はありません。あなたは少なくとも 'var'とキャストを必要とします。これはちょっと悲しいことです。編集を参照してください。 – gourlaysama

+1

バグチケットを掘り下げてくれてありがとう –

関連する問題