我正在看p。 「Programming in Scala」第二版469頁。有一行代碼如下:「<:」在Scala中的含義是什麼?
type Currency <: AbstractCurrency
我不能解釋這是什麼意思。
我正在看p。 「Programming in Scala」第二版469頁。有一行代碼如下:「<:」在Scala中的含義是什麼?
type Currency <: AbstractCurrency
我不能解釋這是什麼意思。
它意味着一個抽象類型構件被定義(裏面的一些方面,例如一個性狀或類),因此,這方面的具體實現必須定義該類型。但是,這種類型(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
}
這意味着「必須是一個子類型」,「必須符合」,「必須擴展」。 大多數時候,它會顯示爲一個泛型參數綁定,比如
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
。
這個問題是關於Scala的,但我認爲這是值得一提的是,<:
[?型operatator]是不是唯一的Scala和而不是類型理論起源;例如參見維基百科上關於Subtyping的文章,其廣泛使用該操作符。實際上,由於它與類型理論的強大聯繫,<:
不是Scala(優雅地)借用的唯一東西;例如term: Type
表示法(見於例如val foo: Foo
,def fact(x: Int): Int
)也來自Type Theory。
我想添加一些要點來描述<的可用性好處:表示法。
讓我們說,您爲您的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,它將不起作用。
參見[什麼是「特質A <:B」是什麼意思?](http://stackoverflow.com/questions/2123663/what-does-trait-a-b-mean) – Jonas