Implicits in Scala
Scala provides implicit conversions and parameters. Implicit conversion to an expected type is the first place the compiler uses implicits. For example, the following works:
scala> val d: Double = 2 d: Double = 2.0
Example 1.65
This works because of the following implicit method definition in the Int
companion object (it was part of Predef
prior to 2.10.x):
implicit def int2double(x: Int): Double = x.toDouble
Example 1.66
Another application of implicit conversion is the receiver of a method call. For example, let’s define a Rational
class:
scala> class Rational(n: Int, d: Int) extends Ordered[Rational] {      |      |   require(d != 0)      |   private val g = gcd(n.abs, d.abs)      |   private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)      |   val numer = n / g      |   val denom = d / g      |   def this(n: Int) = this(n, 1)      |   def +(that: Rational) = new Rational(      |   this.numer * that.numer + this.denom * that.denom,      |   this.denom * that.denom      |   )      |   def compare(that: Rational) = (this.numer * that.numer - this.denom * that.denom)      |   override def toString = if (denom == 1) numer.toString else s"$numer/$denom"      | } defined class Rational
Example 1.67
Then declare a variable of the Rational
type:
scala> val r1 = new Rational(1) r1: Rational = 1 scala> 1 + r1 <console>:14: error: overloaded method value + with alternatives: Â Â (x: Double)Double <and> Â Â (x: Float)Float <and> Â Â (x: Long)Long <and> Â Â (x: Int)Int <and> Â Â (x: Char)Int <and> Â Â (x: Short)Int <and> Â Â (x: Byte)Int <and> Â Â (x: String)String cannot be applied to (Rational) Â Â Â Â Â Â Â 1 + r1 Â Â Â Â Â Â Â Â Â ^
Example 1.68
If we try to add r1
to 1
, we will get a compile-time error. The reason is the +
method in Int
does not support an argument of type Rational
. In order to make it work, we can create an implicit conversion from Int
to Rational
:
scala> implicit def intToRational(n: Int): Rational = new Rational(n) intToRational: (n: Int)Rational scala> val r1 = new Rational(1) r1: Rational = 1 scala> 1 + r1 res11: Rational = 2
Example 1.69