2011-01-17 6 views
57

ScalaのMartin Oderskyのrecent post about levels of programmer abilityで、エキスパートライブラリデザイナーセクションには、"early initializers"という用語が含まれています。Scalaでは、「初期イニシャライザ」とは何ですか?

これらは、Programming in Scalaに記載されていません。彼らは何ですか?

+7

セクション20で説明します。ScalaのProgrammingの5章では、 "pre-initialized fields"と呼ばれていました。 –

答えて

91

初期初期化子は、そのスーパークラスより前に実行されるサブクラスのコンストラクタの一部です。たとえば、次のように

abstract class X { 
    val name: String 
    val size = name.size 
} 

class Y extends { 
    val name = "class Y" 
} with X 

コードが

class Z extends X { 
    val name = "class Z" 
} 

として代わりに書かれていた場合はsizeは、初期化の通常の順序(スーパークラスでname前に初期化されているのでZは、初期化してしまったときに、nullポインタ例外が発生しますクラス前)。

+0

これは、厄介な名前の 'def nameInit:String; val name = nameInit'、 'def nameInit =" foo "'でオーバーライドされていますか? – nadavwr

+1

@nadavwr 'def'はクラスのメソッドテーブルによってオーバーライドされるので、最も具体的なバージョンが確実に実行されますが、' val'初期化のためのものはありません - オーバーライドされるものは初期化ではなくゲッターです。 –

2

は、私の知る限り、(上記のリンクで与えられる)動機は次のとおりです。

「ヴァルが上書きされて当然とき、それを複数回初期化されていないもののしたがって、上記の例では、X2。すべての点で一見定義されていますが、そうではありません:オーバーライドされたvalは、抽象的なvalと同様に、スーパークラスの構築中にnullになるようです。

これがなぜ自然なのかわかりません。 r.h.s.は完全に可能です。割り当ての副作用があるかもしれません。このようなコード構造は、C++やJavaのどちらでも完全に不可能であることに注意してください(私はその言語については話すことができませんが、Smalltalkを推測します)。実際には、暗黙のうちにそのような二重の割り当てを行わなければなりません... ticilpmi ...コンストラクターを介してそれらの言語で明白です。 r.h.sの観点からそれは本当に多くの動機付けのようには見えません。つまり、スーパークラスの副作用を回避して(それによってスーパークラスの不変量を無効にする)能力を割り当てることです。イク!

このような安全でないコード構造を可能にする他の "キラー"の動機はありますか?オブジェクト指向言語は、このような仕組みがなくても約40年(言語の作成から数えれば30年以上)、なぜこれを組み込むのですか?

それはちょうどいいと思われる...危険です。

+0

これは私にとっても完全な意味を成し遂げていません。そして、私が値を上書きし始めたら、私は既に危険な領域にいると主張します。 valに代入されるdefをオーバーライドすると、私にとってもっと意味があります。キックのためのスタイル提案: "暗黙的に..." - 明示的に - > "impli [^ H^H^H^H^H](http://ja.wikipedia.org/wiki/Backspace#.5EH )明示的に " – nadavwr

+0

誰かが明らかに紙ベースの端末を使ったことはありません...はい、子供たちはそれらを一度持っていました:-) –

1

第2の考えでは、年の層...

これは単なるケーキです。文字通り。

初期のものではありません。ちょうどケーキ(ミックスイン)。

ケーキはGrand Pooh-bah自身が作成した用語/パターンで、Scalaの特性システムを採用しています。これはクラスとインターフェイスの中間にあります。 Javaの装飾パターンよりはるかに優れています。

いわゆる「インタフェース」は単なる名前のない基本クラスであり、これまでは基本クラスであったものが特性として機能しています(これは私が率直に言っても実行できませんでした)。 "with'd"クラスが引数を取ることができますか(形質はできません)、それを試して報告するかどうかは私には不明です。

この質問とその答えは、Scalaのクールな機能の1つに入っています。それを読んで畏敬の念を浮かべてください。

+0

ScalaのEBNFから:' ClassTemplate :: = [EarlyDefs] ClassParents [TemplateBody] '、 '' AnnotType} ''と '' Constr :: = AnnotType {'(' [Exprs] ')'} 'を使って、' 'with'd ''クラスが引数を取ることができると思います。 – themarketka

関連する問題