scalascala-wartremover

Throwaway values - what is the best practice in Scala?


WartRemover's NonUnitStatements requires that statements that aren't returning unit must have an assignment. OK, but sometimes we have to use annoying Java APIs that both mutate and return a value, and we don't actually hardly ever care about the returned value.

So I end up trying this:

val _ = mutateSomething(foo)

But if I have multiple of these, _ is actually a legit val that has been assigned to, so I cannot reassign. Wartremover also rightly will admonish for gratuitous var-usage, so I can't just do var _ =.

I can do the following (need the ; to avoid Scala thinking it is a continue definition unless I add a full newline everytime I do this).

;{val _ = mutateSomething(foo)}

Is there a better way?


Solution

  • I'm posting an answer, but the real credit goes to Shane Delmore for pointing this out:

    def discard(evaluateForSideEffectOnly: Any): Unit = {
      val _: Any = evaluateForSideEffectOnly
      () //Return unit to prevent warning due to discarding value
    }
    

    Alternatively (or see @som-snytt's comments below):

    @specialized def discard[A](evaluateForSideEffectOnly: A): Unit = {
      val _: A = evaluateForSideEffectOnly
      () //Return unit to prevent warning due to discarding value
    }
    

    Then use it like: discard{ badMutateFun(foo) }.

    Unlike the ;{ val _ = ... } solution, it looks way better, and also works in the beginning of a block without needing to alter style (a ; can't come at the start of a block, it must come after a statement).