Originally recommended as a must-read on Scala implicit conversions
Martin explains implicit conversions in Programming in Scala Third Edition, mentioning that implicit arguments or implicit conversions may come from the current scope, or from companion objects of the source or target type. The truth is not that simple, and Martin does not go into more depth to explain more about the source. These additional sources of implicit conversions are awesome for library developers and can lead to a cleaner development experience for developers. For example, we often build a JsObject in Play like the following.
import java.time.Instant import play.api.libs.json.Json object Test extends App { println(Json.obj("time" -> Instant.now())) } // exports: {"time":"2018-05-25T18:13:23.409Z"}
But we found outJson.obj() The method signature is as follows:
def obj(fields: (String, JsValueWrapper)*): JsObject
We are not importing any implicit conversions, what is the magic that converts Instant.now() to JsValueWrapper? The reason for this is actually quite simple; one source of implicit conversions is the parent object members of the target type. The parent object of the JsValueWrapper is Json , and the Json object defines the following implicit conversion.
implicit def toJsFieldJsValueWrapper[T](field: T)(implicit w: Writes[T]): JsValueWrapper = JsValueWrapperImpl(w.writes(field))
For more sources of implicit conversions see the official summary of implicit conversion canon。