2012-01-01 23 views
8

とのプライベートメンバの公開サブメンバーを暴露(例は簡略化されますが、すべての重要な部分を含んでいる):パズル - 私はこのような何かをしたいと思いますカスタムタイプ

class Master 
{ 
    type DataType = Int 
    var counter : DataType = 0 
} 

class Slave(private val master : Master) 
{ 
    val counter = master.counter // (*) 
} 

そして、ここで(* )私はエラーを取得する:

private value master escapes its defining scope as part of type Slave.this.master.DataType

val counter = master.counter

私は、エラーを理解し、私はその理由を理解していない - のタイプは、クラスMaster、オブジェクトではありませんmasterの一部であり、そのクラスがプライベートであるかどうかは重要であり、オブジェクトではありません。まあ、少なくとも理論的には。

それは迅速な回避策を作るのは簡単です:

val counter : Master#DataType = master.counter 

しかし、私は、これは以前のようにまったく同じコードの明示的なバージョンであると信じて、それが「唯一」よりタイピングをとります。これは機能ですか?

QUESTION:

タイプ(ここではデータ型が)Scalaでのクラス(クラスのインスタンスごとに、すなわちタイプ定義)オブジェクトの依存性、およびでないことができますか?

答えて

14

あなたは

this is an explicit version of the exactly same code as before

Master#DataTypemaster.DataTypeが2 異なるなタイプだと思うときあなたは間違っています。

master.DataTypeは、masterを外部オブジェクトとして持つこれらのインスタンスのタイプです。言い換えれば、正確にあなたが求めるものですが、明らかにmasterタイプの一部であり、タイプがmasterでない場合は公開できません。

Master#DataTypeは、任意の外部オブジェクトの任意のDataTypeインスタンスのタイプです(JavaではMaster.DataTypeに相当)。コメントに

REPLY:

型部材(1つのオブジェクトのみを含む匿名のサブクラスを含む)のサブクラスにおいて、のみ互換性のある型でオーバーライドすることができます。そして、あなたの例ではDataTypeはすでにMasterに具体的ですので、それと互換性のある唯一のクラスはそれ自身です。だから、

val a = new Master { 
    override type DataType = String 
} 

のようなものは、理にかなっている、です。TypeCheckません:あなたはvar counter: String = 0を取得したい、ナンセンスです。しかし、

val a = new Master { 
    override type DataType = Int 
} 

は機能しますが(それほど有用ではありません)。

抽象タイプのメンバーをオーバーライドするだけです。しかし、内部クラスと同じ方法で型チェックされるので、a.DataTypeは、実際には異なっていなくても、一般的にはb.DataTypeと同じと見なされません。

+0

ありがとう、もし私がこれを正しく理解していれば(しかし、私は「Scalaのプログラミング」でそれを読んでいなかったと思いますが、それがずれたかもしれません)、クラスごとにだけでなく、 。 – greenoldman

+0

更新していただきありがとうございます。残念ながら、私はあなたのポストを1つ以上アップアップすることはできません: – greenoldman

+0

これは、他のOOP言語から来たときに "つかむ"ことができるScalaの便利なものの1つです。非常に簡潔な答え。私のupvoteの価値がある;)。 – TechNeilogy

関連する問題