1

Suppose I wanted to declare in an method declaration somewhere that it could only take a string that was known not to be empty, and not incur any runtime cost for doing so. Something like:

class NonEmptyString(val s: String) extends AnyVal {}
object NonEmptyString {
    def apply(s: String) {
        require(!s.isEmpty)
        new NonEmptyString(s)
    }
}

Would seem to do the trick, but it would in theory allow someone to just new-up another one as required.

If it were not a value class, I could simply put the check in the constructor, but value classes aren't able to have constructors:

scala> class NonEmptyString(val s: String) extends AnyVal { require(!s.isEmpty) }
<console>:7: error: this statement is not allowed in value class
    class NonEmptyString(val s: String) extends AnyVal { require(!s.isEmpty) }

There's a couple of places where this would be a useful technique in my current project, has anyone come up with a good way to add invariants to value classes?

MHarris
  • 1,801
  • 3
  • 21
  • 34
  • 1
    possible duplicate http://stackoverflow.com/questions/9169691/how-to-check-constructor-arguments-and-throw-an-exception-or-make-an-assertion-i – jarandaf Apr 02 '14 at 15:45
  • 3
    You could just make the constructor `private` on the `class`. If you want compile-time invariants though... Only way to do that would probably be through macros, but I don't know nearly enough about them to give you any hints. – Patryk Ćwiek Apr 02 '14 at 16:12
  • For a runtime invariant check, I have thought it would be nice to allow a ctor body (with the require) that is run before all usages. – som-snytt Apr 02 '14 at 17:18
  • @Jaranda Thanks, but not a duplicate - I'll edit to make the difference clearer. – MHarris Apr 03 '14 at 07:58

0 Answers0