I am extending an abstract class which defines an implicit parameter in its constructor.
It seems like there are 3 different ways to do this:
abstract class Base(z: ZType)(implicit a: AType)
// Explicit
class First(z: ZType, a: Atype) extends Base(z)(a)
// Explicitly pass a into the child class which
// implicitly passes it into the parent class
class Second(z: ZType, implicit val a: AType) extends Base(z)
// Implicitly passed into both
class Third(z: ZType)(implicit a: AType) extends Base(z)
Perhaps it depends on how the child class is going to be used. In my case, the child class will not have an implicit AType
in scope, so I was leaning toward the second option.
My biggest concern with the second option is that I now have 2 implicits defined for the same type, one in the parent class and one in the child class. Does that have any effect since they will always be the same object? Is the second pattern one I should avoid for any reason?
Basically, is there a "right" pattern here or are all of these acceptable depending on the context of the code they are used in?
Implicit parameters are the parameters that are passed to a function with implicit keyword in Scala, which means the values will be taken from the context in which they are called.
To extend a class in Scala we use extends keyword. there are two restrictions to extend a class in Scala : To override method in scala override keyword is required.
In Scala, objects and values are treated mostly the same. An implicit object can be thought of as a value which is found in the process of looking up an implicit of its type.
The implicit system in Scala allows the compiler to adjust code using a well-defined lookup mechanism. A programmer in Scala can leave out information that the compiler will attempt to infer at compile time. The Scala compiler can infer one of two situations: A method call or constructor with a missing parameter.
Option 3 is the best one if you think any user of Second
usually wants to pass a
implicitly. They can always go the explicit route, but you just make that a little bit harder, and really explicit. This is good in my opinion, and this is indeed the most common pattern.
Option 1 is the right call if you don't control how Base
is defined, and you want your users to always pass a
explicitly in every case.
Option 2 is never any good, because you can never pass a
implicitly that way and it's just more confusing to read than option 1. Note that the following does not compile.
implicit val a: AType = ???
val z: Type = ???
new Second(z)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With