This is an excerpt from the 1st Edition of the Scala Cookbook (partially modified for the internet). This is Recipe 8.7, “How to declare that a Scala trait can only be mixed into a type that has a specific method.”
Problem
You only want to allow a trait to be mixed into a type (class, abstract class, or trait) that has a method with a given signature.
Solution
Use a variation of the self-type syntax that lets you declare that any class that attempts to mix in the trait must implement the method you specify.
In the following example, the WarpCore trait requires that any classes that attempt to mix it in must have an ejectWarpCore method:
trait WarpCore {
this: { def ejectWarpCore(password: String): Boolean } =>
}
It further states that the ejectWarpCore method must accept a String argument and return a Boolean value.
The following definition of the Enterprise class meets these requirements, and will therefore compile:
class Starship {
// code here ...
}
class Enterprise extends Starship with WarpCore {
def ejectWarpCore(password: String): Boolean = {
if (password == "password") {
println("ejecting core")
true
} else {
false
}
}
}
A trait can also require that a class have multiple methods. To require more than one method, just add the additional method signatures inside the block:
trait WarpCore {
this: {
def ejectWarpCore(password: String): Boolean
def startWarpCore: Unit
} =>
}
class Starship
class Enterprise extends Starship with WarpCore {
def ejectWarpCore(password: String): Boolean = {
if (password == "password") { println("core ejected"); true } else false
}
def startWarpCore { println("core started") }
}
Discussion
This approach is known as a structural type, because you’re limiting what classes the trait can be mixed into by stating that the class must have a certain structure, i.e., the methods you’ve defined. In the examples shown, limits were placed on what classes the WarpCore trait can be mixed into.
See Also
- Recipe 8.5 shows how to limit which Scala classes can use a trait by declaring inheritance
- Recipe 8.6 shows how to mark Scala traits so they can only be used by subclasses of a certain type
| this post is sponsored by my books: | |||
#1 New Release |
FP Best Seller |
Learn Scala 3 |
Learn FP Fast |