Reputation: 333
I came across this code block on this blog. I want to know how h1("Hello World")
is able to compile since h1(children: Frag*)
.
object TheirCode{
trait Frag{
def render: String
}
// HTML constructors
def div(children: Frag*): Frag
def p(children: Frag*): Frag
def h1(children: Frag*): Frag
...
implicit def stringFrag(s: String): Frag
}
object MyCode{
import TheirCode._
val frag = div(
h1("Hello World"),
p("I am a paragraph")
)
frag.render // <div><h1>Hello World</h1><p>I am a paragraph</p></div>
}
I'm guessing the implicit def stringFrag
automatically converts h1(String)
to h1(Frag)
but I always thought the method param would need the implicit prefix for this to work (i.e. implicit h1(children: Frag*)
)
Upvotes: 0
Views: 54
Reputation: 126
In this case we're not talking about implicit parameters at all, but rather implicit conversions. Whenever the compiler finds an A
, but needs a B
, it can automatically apply a function of the form implicit def func(_: A): B
to make the conversion / assignment possible.
Simple example:
implicit def string2int(s: String): Int = s.toInt
val i: Int = "2"
Note that in order for this to work, you either need to either explicitly import scala.language.implicitConversions
or use a compiler flag to enable the feature.
Upvotes: 5