有人可以解释并提供在定义类型时使用with
关键字的真实示例吗?
让我们定义类型
type T = A with B
这是什么意思?
什么时候应该使用?
如何实例化类型T
?
答案 0 :(得分:9)
我猜测它被称为类型连接。
您可以使用它来强制某种类型必须扩展所有指定的特征/类。一个愚蠢的例子:
scala> trait Quackable {
| def quack = println("quack")
| }
defined trait Quackable
scala> trait Walkable {
| def walk = println("walk")
| }
defined trait Walkable
scala> case class Duck(name: String) extends Quackable with Walkable
defined class Duck
scala> def foo(d: Quackable with Walkable): Unit = {
| d.quack
| d.walk
| }
foo: (d: Quackable with Walkable)Unit
scala> foo(Duck(""))
quack
walk
// Or you can create a type alias and use it.
scala> type QW = Quackable with Walkable
defined type alias QW
scala> def foo(d: QW): Unit = {
| d.quack
| d.walk
| }
foo: (d: QW)Unit
scala> foo(Duck(""))
quack
walk
// If you need to retain the type information for some reason, you can use a type parameter.
scala> def foo[A <: Quackable with Walkable](d: A): A = {
| d.quack
| d.walk
| d
| }
foo: [A <: Quackable with Walkable](d: A)A
scala> foo(Duck(""))
quack
walk
res1: Duck = Duck()
至于“如何实例化”:不要那么想。 type
创建类型别名/同义词/函数,它们不一定代表具体的可实例化类型。
修改强>
如果您熟悉Java,则上面使用的with
类似于Java的&
。
public static <QW extends Quackable & Walkable> void foo(QW d) {
d.quack();
d.walk();
}
然而,与Java的&
不同,with
为您提供了合适的类型。我编写的foo
的第一个定义无法转换为Java。此外,您无法使用Java的&
。
scala> case object Quackawalkasaurus extends Quackable with Walkable
defined module Quackawalkasaurus
scala> List(Duck(""), Quackawalkasaurus)
res2: List[Product with Serializable with Quackable with Walkable] = List(Duck(), Quackawalkasaurus)
// Add an explicit type annotation if you want to remove unwanted common super-traits/classes.
scala> List(Duck(""), Quackawalkasaurus) : List[Quackable with Walkable]
res3: List[Quackable with Walkable] = List(Duck(), Quackawalkasaurus)