简体   繁体   中英

Scala: the magic behind implicits

I've been playing with "implicits" in Scala all weekend but I'm still having trouble grasping the whole concept. This question is based off of my previous one . I decided to take things a step further with:

def a(b: String)(implicit c: () => String = () => "") = {
    println(s"$b - up next is "+c());c();b
}

implicit def conv(s: => String) = () => s

That's when things start to get a little whacky:

scala> a("1")(a("2")(a("3")))
3 - up next is 
2 - up next is 3
3 - up next is 
1 - up next is 2
3 - up next is 
2 - up next is 3
3 - up next is 

The basic idea here is to get each line to reference each other like so:

1
2 from 1
3 from 2
4 from 3

  1. Correct me if I'm wrong, but using implicit in this case will insert a string when one is found..? I'm not sure why it's printing out 7 lines instead of 3

  2. What am I doing wrong here? I'm starting to think that using implicits gives me less control

  3. Not as important, but is there a more safe way to go about implicits? A way that allows me to see exactly what's going on?

You are invoking c twice, instead only invoke it once:

def a(b: String)(implicit c: () => String = () => "") = {
  println(s"$b - up next is " + c())
  b
}

Which then produces:

3 - up next is 
2 - up next is 3
1 - up next is 2

Even though a("1") gets invoked first, it has to invoke the () => String it is passed before producing any output. As a result, a("3") is the first one to produce output.

You need to turn this around, and have a("2") tell a("3") that it is being invoked from a("2") :

def a(current: String, next: String => Unit = _ => ())(prev: String) = {
  println(s"$current from $prev")
  next(current)
}

And invoke it like:

a("1", a("2", a("3")))("nothing")

Which produces:

1 from nothing
2 from 1
3 from 2

To answer three of your points:

  1. No, your implicit parameter takes a () => String , not a String .
  2. See above, you don't need implicits here.
  3. Read up on the -Xlog-implicits , -Xlog-implicit-conversions and -Xprint:all options.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM