Test code:
class Prefixer(val prefix: String){
def addPrefix(s: String)(p: Prefixer) = p.prefix + s
}
Consumer code:
val myImplicitPrefixer = new Prefixer("***")
println(myImplicitPrefixer.addPrefix("abc")(myImplicitPrefixer)) // returns "***abc"
The implementation of Prefixer is combined to Java Byte code as below.
The argument list in Scala is converted into flat format (s: String)(p: Prefixer) as below:
The following two styles are actually equal:
def addPrefix(s: String, p: Prefixer) = p.prefix + s
def addPrefix(s: String) (p: Prefixer) = p.prefix + s
Now let's make a little bit modification:
def addPrefix(s: String)(implicit p: Prefixer) = p.prefix + s
And consumer code:
Still ***abc is printed out. What's the magic here?
When we debug into line 26, although in our application code, we only pass "abc" as parameter for method addPrefix.
The parameter p is filled with the reference myImplicitPrefixer marked with keyword implicit in line 25:
p actually points to the same reference of this:
This is the compiled byte code for method addPrefix, the implicit parameter p is already in the method's signature.
And in the consumer code, the reference of Prefixer is automatically passed into addPrefix method:
One more point, the variable defined in class definition parameter will automatically become member of this class: