在Scala中没有等价的标志吗?
类似于:
val flags = Something | SomeOtherThing
我想我可以为每个标志集做一个类,并有一堆布尔值,但语法糖呢?
这在很大程度上取决于您想要实现的目标。
如果您正在使用遗留代码(尤其是无法修改的代码)和/或需要超高效率,则一种规范的方法是为Int
创建类型别名。即,如链接库中的示例:
type MyFlags = Int
...
val theseFlags: MyFlags
与仅使用Int
相比,优势在于您可以用类型别名"标记"这些标志的任何用法——这可以极大地提高代码的可读性,并有助于避免由于"混淆"标志而导致的错误。
对于这种方法,在Scala特定的代码中,您可以通过(ab)使用BitSet来帮助自己(更多信息请点击此处)。
如果您想创建一个更"对象友好"的实现,该解决方案类似于Java的enum
/EnumSet
组合,即将Enumeration
与ValueSet
一起使用。一个改编自图书馆文档的例子:
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)
ValueSet
和Value
出现了一个问题-它们缺乏类型参数化,允许混合两种不同类型的标志。当然,与Java的EnumSet
相比,这只是一个不足。在Scala的上下文中,解决方法与Int
示例中完全相同——使用type
别名,这次是针对Value
(如上所示)。
此外,您的所有旗帜都有唯一的名称。
作为形式,我还应该提到价值类。与类型别名一起,它们将允许您向标志添加自定义运算符,同时保持Int
s的效率。
然而,对于大多数使用场景来说,这可能有些过头了——通常最好使用第二种基于Enumeration
的方法。对于大多数情况,它应该足够有效,特别是因为ValueSet
实际上是BitSet
的一个薄包装。
如果您的Something
或SomeOtherThing
是数字,这应该会起作用。
如果你想让它更明显,试着指定类型:
val flags : Int = Something | SomeOtherThing
位运算符应该像在Java中一样在Scala中工作。我在谷歌上找到了这个简短的解释,你可能会觉得很有帮助。
如果你不更新mikolak帖子中的一行,你可能会遇到很多关于Weekday.type
和Weekday.Value
之间冲突的令人困惑的错误消息。
更新
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = WeekDay
至
val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value