문제

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?

도움이 되었습니까?

해결책

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.

다른 팁

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
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top