5

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

就像是 :

val flags = Something | SomeOtherThing

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

4

3 回答 3

8

这在很大程度上取决于您要完成的工作。

如果您正在与遗留代码(尤其是您无法修改的代码)交互和/或需要超高效率通常不需要),一种规范的方法 是为Int. 即,如在链接库示例中:

type MyFlags = Int
...
val theseFlags: MyFlags

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

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


如果你想创建一个更“对象友好”的实现,解决方案类似于 Java 的enum/EnumSet组合- 即使用EnumerationwithValueSet。改编自图书馆文档的示例:

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它们缺乏类型参数化允许混合两种不同类型的标志。当然,这只是与 Java 的. 在 Scala 的上下文中,解决方法与示例中的完全相同- 使用别名,这次是 for (如上所示)。ValueEnumSetInttypeValue

作为额外的奖励,你所有的旗帜都有唯一的名字


作为备考,我还应该提到Value Classes。与类型别名一起,它们将允许您在标志中添加自定义运算符,同时保持Ints 的效率。

但是,对于大多数使用场景来说,这可能有点过头了——通常最好使用第二种Enumeration基于 - 的方法。在大多数情况下,它应该足够有效,尤其是因为ValueSet它实际上是BitSet.

于 2014-02-24T20:32:08.743 回答
3

如果您的SomethingorSomeOtherThing是数字,这应该有效。

如果您想让它更明显,请尝试指定类型:

val flags : Int = Something | SomeOtherThing

位运算符在 Scala 中的工作方式与在 Java 中的工作方式非常相似。我在谷歌上找到了这个简短的解释,你可能会觉得有帮助。

于 2014-02-24T18:18:45.240 回答
1

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

更新

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

val Mon, Tue, Wed, Thu, Fri, Sat, Sun = Value
于 2017-10-10T21:40:15.253 回答