JohnB
JohnB

Reputation: 4359

What is the meaning of "implicit val" in a Scala class definition?

I'm working on coming up to speed with Scala and am a little confused about usage of the keyword "implicit."

I think I understand the notion of implicit parameters, where the parameters are not explicitly passed in, Scala will search for a value of the correct type (within the calling scope).

I'm confused with the use of "implicit val."

Consider the following code snippet:

case class DemoApp() {
   implicit val foo = CustomerFoo()
}

Does this have to do with parameters passed into the DemoApp() class constructor?

Can someone please clarify?

Thx, JohnB

Upvotes: 3

Views: 4019

Answers (1)

Jörg W Mittag
Jörg W Mittag

Reputation: 369420

think I understand the notion of implicit parameters, where the parameters are not explicitly passed in,

This is just the other side of the coin.

Scala will search for a value of the correct type (within the calling scope).

Yes, but it will not just take any random value. Only values that are explicitly marked implicit.

There are four uses of an implicit modifier, which are related in pairs.

One pair is related to implicit parameters. When applied to a parameter in a parameter list, implicit means "this argument does not need to be supplied explicitly, it can be searched in the context of the call". When applied to a val or an object, in turn, it means "this value can be passed as an implicit argument".

The other pair is related to implicit conversions. When implicit is applied to a method definition of a method with one parameter, it means "whenever you need a value of the return type, but you only have a value of the parameter type, you can use this method to convert from the argument value to the return value".

E.g. if I have something like this:

implicit def string2Tuple2(s: String): (Int, Int) = {
  val l = s.split(",")
  (l(0).toInt, l(1).toInt)
}

Then, whenever Scala expects a (Int, Int), I can also pass a String instead, and Scala knows that it can call string2Tuple to convert it:

val m = Map.empty[Int, Int]

m + "2,3"
//=> val res1: scala.collection.immutable.Map[Int,Int] = Map(2 -> 3)

This is of course a stupid example. A more useful example is the enrich-my-library idiom, where we create a new class that augments an existing class with some new functionality, and then provide an implicit conversion from the old type to the enriched type:

class HelloString(s: String) {
  val hello = "Hello " + s + " World"
}

implicit def string2HelloString(s: String) = new HelloString(s)

"beautiful".hello
//=> val res2: String = Hello beautiful World

This is where the second use for the implicit modifier comes in. An implicit class is simply syntactic sugar for a wrapper class + an implicit conversion, meaning the above is exactly equivalent to:

implicit class string2HelloString(s: String) {
  val hello = "Hello " + s + " World"
}

There you have it, the four uses of the implicit modifier in two related pairs.

Upvotes: 8

Related Questions