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 |