I'm looking at the akka streams quickstart tutorial and I wanted to understand how a piece of code works. The following code from the example prints out the values from 1 to 100 to the console:
import akka.stream.scaladsl._
import akka.{Done, NotUsed}
import akka.actor.ActorSystem
object Akka_Streams extends App{
implicit val system: ActorSystem = ActorSystem("QuickStart")
val source: Source[Int, NotUsed] = Source(1 to 100)
source.runForeach(i => println(i))
}
What I don't understand is, when I change the code to the following and remove the implicit, the code no longer works. I get a type mismatch error (shown below the following code):
object Akka_Streams extends App{
val system: ActorSystem = ActorSystem("QuickStart")
val source: Source[Int, NotUsed] = Source(1 to 100)
source.runForeach(i => println(i))(system)
}
Error:
type mismatch; found : akka.actor.ActorSystem required: akka.stream.Materializer source.runForeach(i => println(i))(system)
Why did this work before but not now? the source.runForeach
method takes a Materalizer
type so I wonder why this was working at all to begin with? From what I can see, an ActorSystem
is not a Materalizer
or a sub-type of it so I'm confused.
CodePudding user response:
It is related to how Scala compiler converts ActorSystem
to a Materializer
It is done via implicit conversions with following method
/**
* Implicitly provides the system wide materializer from a classic or typed `ActorSystem`
*/
implicit def matFromSystem(implicit provider: ClassicActorSystemProvider): Materializer =
SystemMaterializer(provider.classicSystem).materializer
It requires parameter provider
to be implicit
.
So having implicit
key is allowing the compiler to take an implicit actor system when it needs an instance of a Materializer
, and such conversion is done without any need to explicitly define a materializer in the scope.