scala

convert from Option[String] to Long in Scala?


I have a function that needs to be pass in a long value. As code block example below:

val expectTime = sys.env.getOrElse("envVar", "1000").toLong
pause(expectTime.milliseconds)

When I try to compile this, it will return that value milliseconds is not a member of Long although I can run this code:

java.long.getLong("var", 1000L)
pause(expectTime.milliseconds)

Digging a bit, I saw that getOrElse will return Option[String], but I'm not sure what went wrong with my conversion that lead to the function "not accepting" the long value there. Is there a way for this one?


Solution

  • First of all, as Gaël mentioned, the main issue is probably missing an import like: scala.concurrent.duration._ to allow the conversion.

    Second, we can improve the way we get the value our of the Env to make it safer and avoid parsing constant values.

    val expectTime =
      sys
        .env
        .get(key = "envVar")
        .flatMap(_.toLongOption)
        .getOrElse(default = 1000L)
    

    This is safer because if the value inside the envVar is not a number it will not throw an exception but rather just fallback to the default. An also, in the case we fallback to the default we can just use a literal Long.


    Let's break the code step by step to make it easier to read.

    sys // This is the system object the stdlib provides.
      .env // We access the environment from the system, its type is a Map[String, String]
      .get(key = "envVar") // We try to get the env var called 'envVar', this returns an Option[String]
      .flatMap(_.toLongOption) // We then transform that Option[String] into an Option[Long] by trying to parse the value (if it exists) as a Long.
      .getOrElse(default = 1000L) // Finally, we either get the value inside the Option if any, or we return a default value. Meaning the result is a plain Long.