Could someone explain and provide real world examples of using with
keyword in defining types?
Let's define type
type T = A with B
What does it mean? When should it be used? How to instantiate type T
?
I guess it's called type conjunction.
You can use it to enforce that a certain type must extend all of the specified traits / classes. A stupid example:
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()
As for "how to instantiate it": don't think of it that way. type
creates type aliases / synonyms / functions, which do not necessarily represent concrete instantiable types.
Edit:
If you're familiar with Java, with
as used above is similar to Java's &
.
public static <QW extends Quackable & Walkable> void foo(QW d) {
d.quack();
d.walk();
}
However unlike Java's &
, with
gives you a proper type. The first definition of foo
I wrote cannot be translated to Java. Also you cannot do the following with Java's &
.
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)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.