2011-07-26 9 views
31

私はpを見ています。 "Programming in Scala"第2版の469ページ。Scalaでは "<:"の意味は何ですか?

type Currency <: AbstractCurrency 

私はこれが何を意味するのか解読できません。

+5

「[特性A <:B」とはどういう意味ですか?」(http://stackoverflow.com/questions/2123663/what-does-trait-a-b-mean) – Jonas

答えて

46

抽象型メンバーが定義されていることを意味します(つまり、特性やクラスなど)。そのコンテキストの具体的な実装でその型を定義する必要があります。ただし、このタイプ(Currency)は実際にサブタイプAbstractCurrencyでなければならないという制約があります。このようにして、抽象的なコンテキストは、AbstractCurrencyのすべての操作を理解していることを知って、Currencyで操作できます。

trait AbstractCurrency { 
    def disappearInGreece(): Unit 
} 

abstract class Economy { 
    type Currency <: AbstractCurrency 

    def curr: Currency 

    // can call disappear... because `Currency` 
    // is an `AbstractCurrency` 
    def shake(): Unit = curr.disappearInGreece() 
} 

制約なしCurrencyを定義しようとすると:

trait RadioactiveBeef 

class NiceTry(val curr: RadioactiveBeef) extends Economy { 
    type Currency = RadioactiveBeef 
} 

は失敗します。[OK]を制約付き:

trait Euro extends AbstractCurrency 

class Angela(val curr: Euro) extends Economy { 
    type Currency = Euro 
} 
21

「必ずサブタイプでなければなりません」、「一致する必要があります」、「必ず延長する」を意味します。 時間のほとんどは、そのような

class Home[P <: Person] 

などの一般的なパラメータにバインドされ、各家庭は、人の特定のタイプに適合しているとして、Home[Person]はすべての人を受け入れると思われる、Home[Student]Home[Elderly]があるかもしれませんいいえHome[Planet]はありません。

type Currency <: AbstractCurrencyは、それが表示されますclass/traitに抽象typeメンバーCurrencyを紹介します。子孫は、具体的にできるように型を選択する必要があります。 <:AbstractCurrenciesでは、サブタイプがAbstractCurrencyAbstractCurrencyを含む)が選択できます。

抽象型メンバーは、抽象型値メンバーがコンストラクターパラメーターに近いので、型パラメーターに非常に近いです。

class A(val x: X){...}がある場合、最初にでインスタンス化します。 class A{val x: X; ...}をお持ちの場合は、新しいA{val x = myX }でインスタンスを作成します。

class Market[Currency <: AbstractCurrency]がある場合は、タイプをMarket[SomeCurrencyType]でインスタンス化します。 Market{type Currency <: AbstractCurrency}がある場合、Market{type Currency = SomeCurrencyType}でインスタンス化します。ただし、Marketは有効なタイプです。これは、この市場がどのタイプの通貨を使用しているのかわからないことを意味します(使用方法を制限する可能性があります)。 Marketは、関数のパラメータまたは結果として表示される何Currencyを持っていない場合は、typeパラメータの型のパブリックインターフェイスに表示されていない、ほとんど場合、利点を有することができる抽象型メンバーではなく、型パラメータを使用して

(ではありませんこの例ではあまりにも可能性が高い)。クライアントはMarket[SomeCurrencyType]Marketを書く必要はありません。もちろん、CurrencyTypeは、マーケットが作成されたときに知っておく必要がありますが、その後は単にMarketとして渡すことができます。

3

この質問はスカラ座についてですが、私はそれが<: [?型、演算子]はスカラ座に固有のものではなく、代わりに、型理論に由来することを言及する価値だと思います。例えば、この演算子を広く使用するWikipediaのSubtypingに関する記事を参照してください。

実際、タイプ理論との強い結びつきのために、<:はスカラ(エレガントに)から借りたものだけではありません。例えば、term: Typeの表記(例えば、val foo: Fooに見られる、def fact(x: Int): Int)は、Type Theoryから来る。

0

<の表記法のユーザビリティ上の利点を説明するいくつかの点を追加したいと思います。

あなたのAPIのための次のクラスを定義し、私たちが言ってみましょう:

case object Parameter1 extends BaseParameter 
case object Parameter2 extends BaseParameter 
case object Parameter3 

case class myApiClass[param <: BaseParameter](requestBody: String, parameter: param) 

あなたが次に

trait BaseParameter 

BaseParameter

と呼ばれる形質を持っている、あなたは以下のパラメータを持っています

これで、myApiClassインスタンスを作成するたびに、オブジェクトを引数「パラメータ」として渡す必要があります。そのクラス/自体がBaseParameterを実装しています(例:パラメータ1およびパラメータ2)。具体的には、これはアサーションであり、Parameter3を渡すと機能しません。

関連する問題