Scala中的“&lt ;:”是什么意思?

时间:2011-07-26 10:48:12

标签: scala

我在看p。 “Scala编程”第二版469。有一行代码如下:

type Currency <: AbstractCurrency

我无法破译这意味着什么。

4 个答案:

答案 0 :(得分:54)

这意味着定义了一个抽象类型成员(在某些上下文中,例如特征或类),因此该上下文的具体实现必须定义该类型。但是,这种类型(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
}

答案 1 :(得分:30)

这意味着“必须是”的子类型,“必须符合”,“必须延伸”。 大多数情况下,它会显示为泛型参数的绑定,例如

class Home[P <: Person] 

每个家庭适合某种类型的人,Home[Person]接受任何人,可能有Home[Student]Home[Elderly],但没有Home[Planet]

type Currency <: AbstractCurrency在其显示的type / Currency中引入了一个抽象的class成员trait。后代必须选择一种类型才能具体。 &lt ;: AbstractCurrencies强制他们选择AbstractCurrency的子类型(包括AbstractCurrency,这是允许的)。

抽象类型成员非常接近类型参数,就像抽象值成员接近构造函数参数一样。

如果您有class A(val x: X){...},则使用new A(myX)将第一个实例化。如果您有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没有{{ 1}}作为函数参数或结果出现(在此示例中不太可能)。然后客户端不需要写CurrencyMarket[SomeCurrencyType]会这样做。当然,在创建市场时必须知道Market,然后它可以简单地作为CurrencyType传递。

答案 2 :(得分:5)

我想添加一些点来描述&lt ;: notation的可用性优势。

我们假设您为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实例,都必须传递一个对象作为参数&#34;参数&#34;,其类/本身实现BaseParameter(例如Parameter1和Parameter2)。具体来说,这是一个断言,如果你传递Parameter3就行不了。

答案 3 :(得分:4)

这个问题是关于Scala的,但我认为值得一提的是<: [类型操作符?]并不是Scala独有的,而是源于类型理论;例如,请参阅维基百科上有关Subtyping的文章,该文章广泛使用了此运算符。

事实上,由于它与类型理论的紧密联系<:并不是Scala(优雅地)借用它的唯一东西;例如,term: Type表示法(例如val foo: Foodef fact(x: Int): Int中)也来自Type Theory