Rory Rory - 1 month ago 12
Scala Question

Pattern matching on a Try lazy val in Scala?

Is it possible to pattern match on a

lazy val
, declared as a
, like this?

lazy val kafkaProducer: Try[producer.KafkaProducer[Array[Byte], String]] = Try(kafkaProducerSettings.createKafkaProducer())
kafkaProducer.get match {
case Success(_) => Source.single(producerRecord()).runWith(Producer.plainSink(kafkaProducerSettings, kafkaProducer.get))
case Failure(x) => Future.failed(x)

I'm getting this error:

constructor cannot be instantiated to expected type;
[error] found :
[error] required: org.apache.kafka.clients.producer.KafkaProducer[Array[Byte],String]
[error] case Success(_) => Source.single(producerRecord()).runWith(Producer.plainSink(kafkaProducerSettings, kafkaProducer.get))

Note, this alternative code works, but I'm not sure it's the "Scala way":

lazy val kafkaProducer: producer.KafkaProducer[Array[Byte], String] = kafkaProducerSettings.createKafkaProducer()
val tryAccessLazyKafkaProducer = Try(kafkaProducer)
if (tryAccessLazyKafkaProducer.isSuccess) {
Source.single(producerRecord()).runWith(Producer.plainSink(kafkaProducerSettings, kafkaProducer))
} else {

Answer Source

It's definitely possible, you just have the wrong Success type imported:

found   :

You need scala.util.Success instead

One thing you mustn't do is call Try.get, which will explode if the returned type is a Failure. Instead, do:

import scala.util.Success
import scala.util.Failure

kafkaProducer match {
    case Success(producer) => Source.single(producerRecord()).runWith(Producer.plainSink(kafkaProducerSettings, producer))
    case failure: Failure => failure

lazy is just a language construct which makes sure the value is only ever evaluated once. The underlying type, whether lazy or not, is still a Try which you can do what you do with it.