Domanda

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?

È stato utile?

Soluzione

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.

Altri suggerimenti

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.

You may run into a lot of confusing error messages about conflicts between Weekday.type and Weekday.Value if you don't update one line from the mikolak's post.

Update

val Mon, Tue, Wed, Thu, Fri, Sat, Sun = WeekDay

to

val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top