Scala相当于标志



在Scala中没有等价的标志吗?

类似于:

val flags = Something | SomeOtherThing

我想我可以为每个标志集做一个类,并有一堆布尔值,但语法糖呢?

这在很大程度上取决于您想要实现的目标。

如果您正在使用遗留代码(尤其是无法修改的代码)和/或需要超高效率,则一种规范的方法是为Int创建类型别名。即,如链接库中的示例:

type MyFlags = Int
...
val theseFlags: MyFlags

与仅使用Int相比,优势在于您可以用类型别名"标记"这些标志的任何用法——这可以极大地提高代码的可读性,并有助于避免由于"混淆"标志而导致的错误。

对于这种方法,在Scala特定的代码中,您可以通过(ab)使用BitSet来帮助自己(更多信息请点击此处)。


如果您想创建一个更"对象友好"的实现,该解决方案类似于Java的enum/EnumSet组合,即EnumerationValueSet一起使用。一个改编自图书馆文档的例子:

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)

ValueSetValue出现了一个问题-它们缺乏类型参数化,允许混合两种不同类型的标志。当然,与Java的EnumSet相比,这只是一个不足。在Scala的上下文中,解决方法与Int示例中完全相同——使用type别名,这次是针对Value(如上所示)。

此外,您的所有旗帜都有唯一的名称


作为形式,我还应该提到价值类。与类型别名一起,它们将允许您向标志添加自定义运算符,同时保持Ints的效率。

然而,对于大多数使用场景来说,这可能有些过头了——通常最好使用第二种基于Enumeration的方法。对于大多数情况,它应该足够有效,特别是因为ValueSet实际上是BitSet的一个薄包装。

如果您的SomethingSomeOtherThing是数字,这应该会起作用。

如果你想让它更明显,试着指定类型:

val flags : Int = Something | SomeOtherThing

位运算符应该像在Java中一样在Scala中工作。我在谷歌上找到了这个简短的解释,你可能会觉得很有帮助。

如果你不更新mikolak帖子中的一行,你可能会遇到很多关于Weekday.typeWeekday.Value之间冲突的令人困惑的错误消息。

更新

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

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

最新更新