2011-07-26 132 views
31

我正在看p。 「Programming in Scala」第二版469頁。有一行代碼如下:「<:」在Scala中的含義是什麼?

type Currency <: AbstractCurrency 

我不能解釋這是什麼意思。

+5

參見[什麼是「特質A <:B」是什麼意思?](http://stackoverflow.com/questions/2123663/what-does-trait-a-b-mean) – Jonas

回答

46

它意味着一個抽象類型構件被定義(裏面的一些方面,例如一個性狀或類),因此,這方面的具體實現必須定義該類型。但是,這種類型(Currency)實際上必須是子類型AbstractCurrency。這樣,抽象上下文可以與Currency一起操作,知道它理解AbstractCurrency的每個操作。

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 
} 

失敗。隨着制約確定:

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引入了一個抽象type構件Currency在它出現在class/trait。後裔將不得不選擇一種類型,以便他們可以具體。 <:AbstractCurrencies強制他們選擇AbstractCurrency的子類型(包括AbstractCurrency,這是允許的)。

抽象型部件是非常接近的類型參數,只是作爲一個抽象值構件靠近一個構造符參數。

如果你有class A(val x: X){...},你實例化先用new A(myX)。如果你有class A{val x: X; ...},你可以用新的A{val x = myX } instanciate。

如果你有class Market[Currency <: AbstractCurrency]你實例化與Market[SomeCurrencyType]類型。如果你有Market{type Currency <: AbstractCurrency},你用Market{type Currency = SomeCurrencyType}實例化。但是,Market是有效的類型。這意味着你不知道這個市場使用什麼類型的貨幣(這可能會限制你如何使用它)。

使用一個抽象類型成員而不是一個類型參數可以有優惠,主要是如果類型參數沒有出現在該類型的公共接口,如果Market沒有Currency出現作爲函數參數或結果(不這個例子很可能)。那麼客戶端不需要寫Market[SomeCurrencyType]Market就可以。當然,創建市場時必須知道CurrencyType,但它可以簡單地通過Market

3

這個問題是關於Scala的,但我認爲這是值得一提的是,<: [?型operatator]是不是唯一的Scala和而不是類型理論起源;例如參見維基百科上關於Subtyping的文章,其廣泛使用該操作符。實際上,由於它與類型理論的強大聯繫,<:不是Scala(優雅地)借用的唯一東西;例如term: Type表示法(見於例如val foo: Foo,def fact(x: Int): Int)也來自Type Theory

0

我想添加一些要點來描述<的可用性好處:表示法。

讓我們說,您爲您的API以下類:

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

您有一個名爲BaseParameter

trait BaseParameter 

然後,您有以下參數特徵:

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

現在,無論何時創建myApiClass實例,都必須傳遞一個對象作爲參數「parameter」,其類/它本身實現了BaseParameter(例如,參數1和參數2)。具體來說,這是一個斷言,如果你傳遞Parameter3,它將不起作用。

相關問題