我正在看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