【问题标题】:F# bit flags enumF# 位标志枚举
【发布时间】:2016-09-29 13:19:13
【问题描述】:

我想在 F# 中创建一个 bitflags 枚举,使用移位运算符来提高可读性:例如

[<Flags>]
type DaysOfWeek =
    | Monday = 1 <<< 0
    | Tuesday = 1 <<< 1
    | Wednesday = 1 <<< 2
    | Thursday = 1 <<< 3
    | Friday = 1 <<< 4
    | Saturday = 1 <<< 5
    | Sunday = 1 <<< 6

但是,F# 编译器不喜欢这样。它说“成员定义中出现意外的中缀运算符”。

我更喜欢这种方法,而不是手动的二次幂。有没有办法让编译器相信我不是邪恶的?

【问题讨论】:

    标签: f#


    【解决方案1】:

    这不完全符合您的要求,但您可以使用0b 前缀编写二进制速记,例如:

    [<Flags>]
    type DaysOfWeek =
        | Monday    = 0b0000001
        | Tuesday   = 0b0000010
        | Wednesday = 0b0000100
        | Thursday  = 0b0001000
        | Friday    = 0b0010000
        | Saturday  = 0b0100000
        | Sunday    = 0b1000000
    

    【讨论】:

    • 对我来说已经足够了。
    【解决方案2】:

    将案例与值分开的替代方法,更详细但更灵活:

    type DaysOfWeek =
      | Monday
      | Tuesday
      | Wednesday
      | Thursday
      | Friday
      | Saturday
      | Sunday
      with
        static member Flag x =
          let bit n = 1 <<< n
          match x with
          | Monday ->    bit 0
          | Tuesday ->   bit 1
          | Wednesday -> bit 2
          | Thursday ->  bit 3
          | Friday ->    bit 4
          | Saturday ->  bit 5
          | Sunday ->    bit 6
    

    【讨论】:

      【解决方案3】:

      这是 Dave Fancher 在The Book of F#

      中推荐的方法

      使用带有 2 次幂的值的 Flags 属性:

      open System
      
      [<Flags>]    
      type DayOfWeek =
        | None = 0
        | Sunday = 1
        | Monday = 2
        | Tuesday = 4
        | Wednesday = 8
        | Thursday = 16
        | Friday = 32
        | Saturday = 64
      

      Flags 属性不是必需的,但可以明确您的意图。

      您现在可以使用按位运算符表示值的组合:

      let weekend = DayOfWeek.Saturday ||| DayOfWeek.Sunday
      

      【讨论】:

      • 我觉得这只是马克拉姆回答的一步。
      • 所以你认为二进制比整数更易读和故障安全?如果您有大量物品怎么办?
      • 没错。必须破译更多标志的十进制表示是没有希望的。您甚至不需要大量的项目来证明这一点,因为像| Weekend = 65| Workdays = 62 这样的附加组合标志定义对于这种情况来说已经足够困难了。二进制表示将立即揭示含义。
      • 为了避免混淆,这个答案不使用与问题和其他答案相同的标志值。
      • 哎呀——我刚刚注意到 OP 明确首选二进制而不是手动的两个幂。我将保留答案,因为您的 cmets 说明了为什么接受的答案比书中的建议更好。感谢您的教育。
      猜你喜欢
      • 1970-01-01
      • 2018-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多