Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala equivalent of flags

Isn't there an equivalent for flags in Scala ?

Something like :

val flags = Something | SomeOtherThing

I guess I could do a class for each flag set and have a bunch of booleans but what about syntactic sugar?

like image 664
Théo Winterhalter Avatar asked Feb 24 '14 18:02

Théo Winterhalter


2 Answers

It largely depends on what you're trying to accomplish.

If you're interfacing with legacy code (especially one that you cannot modify) and/or need super-extra-high efficiency (you usually don't), a canonical way is to create a type alias for Int. I.e., as in the linked library example:

type MyFlags = Int
...
val theseFlags: MyFlags

The advantage over merely using Int is that you can "mark" any usage of those flags with the type alias - this can help immensely with code readability and help avoid bugs due to "mixing up" flags.

For this approach, within Scala-specific code, you can assist yourself by (ab)using BitSet (more info here).


If you want to create a more "object-friendly" implementation, the solution is similar to Java's enum/EnumSet combo - namely, use Enumeration with ValueSet . An example adapted from the library doc:

scala>   object WeekDay extends Enumeration {
     |     type WeekDay = Value
     |     val Mon, Tue, Wed, Thu, Fri, Sat, Sun = WeekDay
     |   }
defined module WeekDay

scala>   import WeekDay._
import WeekDay._

scala> var newSet = ValueSet.empty
newSet: WeekDay.ValueSet = WeekDay.ValueSet()

scala> newSet += Mon

scala> newSet
res1: WeekDay.ValueSet = WeekDay.ValueSet(Mon)

scala> newSet & WeekDay.values
res2: WeekDay.ValueSet = WeekDay.ValueSet(Mon)

A problem with ValueSet and Value arises - their lack of type-parametrization allows for mixing two different types of flags. Of course, this is only a deficiency when compared to Java's EnumSet. In the context of Scala, the workaround is exactly the same as in the Int example - use a type alias, this time for Value (as shown above).

And as an added bonus, all your flags have unique names.


As a pro-forma, I should also mention Value Classes. Together with a type alias, they would allow you to add custom operators to your flags while preserving the efficiency of Ints.

However, that's likely an overkill for most usage scenarios - you're usually better off using the second, Enumeration-based approach. It should be sufficiently efficient for most cases, especially since ValueSet is really a thin wrapper around BitSet.

like image 53
mikołak Avatar answered Sep 29 '22 07:09

mikołak


If your Something or SomeOtherThing are numbers, this should work.

If you want to make it more obvious, try specifying the type:

val flags : Int = Something | SomeOtherThing

Bitwise operators should work in Scala pretty much like they work in Java. I've found this brief explanation on Google, which you might find helpful.

like image 38
lucian.pantelimon Avatar answered Sep 29 '22 07:09

lucian.pantelimon