I am reading a Spark in Action book, I came across a construct that even after a while working with Scala I still can't understand. Here is the code (complete code) :
First we have a case class where RDD will be converted to DataFrame using this case class:
import java.sql.Timestamp
case class Post(
commentCount:Option[Int],
lastActivityDate:Option[java.sql.Timestamp],
ownerUserId:Option[Long],
body:String,
score:Option[Int],
... )
Then we define an object with implicit class
object StringImplicits {
implicit class StringImprovements(val s: String) {
import scala.util.control.Exception.catching
def toIntSafe = catching(classOf[NumberFormatException]) opt s.toInt
def toLongSafe = catching(classOf[NumberFormatException]) opt s.toLong
def toTimestampSafe = catching(classOf[IllegalArgumentException]) opt
Timestamp.valueOf(s)
}
}
Then we import the object which is already in scope for some reason and now looks like all String object has the three methods defined in StringImprovements
import StringImplicits._
def stringToPost(row: String): Post = {
val r = row.split("~")
Post(r(0).toIntSafe,
r(1).toTimestampSafe,
r(2).toLongSafe,
r(3),
...
}
Questions:
- Why do we need to need to import an already in scope object?
- Which statement exactly assigned these methods to the String object, this is so confusing?
Reading implicit classes doc it makes some sense but not everything is clear. For example how come this is a valid expression
scala> 5 times println("HI")
I understand if it was
IntWithTimes(5).time(println("HI"))