Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala类位方法参数_Scala_Arguments_Bit Manipulation - Fatal编程技术网

Scala类位方法参数

Scala类位方法参数,scala,arguments,bit-manipulation,Scala,Arguments,Bit Manipulation,假设有一个通用方法声明,它根据指定的模式执行一组操作,该模式如下所示: def doSomethingSmart(mode: OpMode, someGoodyList: List[Any]): Boolean = { /* do foo */ } object OpMode extends Enumeration { type OpMode = Value val Read, Write, Create, Modify, Delete, Whatever = Value } 其中O

假设有一个通用方法声明,它根据指定的模式执行一组操作,该模式如下所示:

def doSomethingSmart(mode: OpMode, someGoodyList: List[Any]): Boolean = { /* do foo */ }
object OpMode extends Enumeration {
  type OpMode = Value
  val Read, Write, Create, Modify, Delete, Whatever = Value
}
其中OpMode是一种类型/枚举,包括:

  • 阅读
  • 创造
  • 删除
  • 修改
  • 随便
  • 将两者结合在一起显然会产生一个单模、可重用的代码块。

    现在,类型/枚举部分可能如下所示:

    def doSomethingSmart(mode: OpMode, someGoodyList: List[Any]): Boolean = { /* do foo */ }
    
    object OpMode extends Enumeration {
      type OpMode = Value
      val Read, Write, Create, Modify, Delete, Whatever = Value
    }
    
    但假设您想扩展doSomethingSmart()的范围,以涵盖通常使用位运算符所做的工作,例如:创建和修改&随便什么。是否有一种“scala方式”将位掩码参数限制为该有限的数据集(即枚举/类型)。也许是这样的:

    def doSomethingSmarter(more: T < [BitwiseSelectionOf[OpMode]], ...
    
    def doSomethingSmarter(更多信息:T<[OpMode]的位选择]。。。
    
    或者,最好还是简单地返回到二进制索引值赋值——在这种情况下,没有“类型”检查本身

    蒂亚

    编辑:我想另一种可能是将OpMode更改为列表,然后只运行一系列“包含”操作


    编辑2:特别是,我一直在寻找一种有效的机制,在调用doSomethingSmarter()时提供一个内联构造。枚举定义了一个名为ValueSet的内部类型,它至少提供了一些您正在寻找的功能。它上面的方法仍然设置为(您可以使用
    +
    添加一个新模式,并使用
    检查模式是否包含
    ),但它可以满足您的需要

    编辑:玩得很开心,想出了这个:

    import scala.collection.BitSet
    
    object OpMode extends Enumeration {
    
      protected case class Val(name: String, val mask: Int) extends super.Val(nextId, name)
    
      type OpMode = Val
    
      val Read = Val("Read", 1)
      val Write = Val("Write", 2)
      val Create = Val("Create", 4)
      val Modify = Val("Modify", 8)
      val Delete = Val("Delete", 16)
      val Whatever = Val("Whatever", 32)
    
      case class FlagSet(bits: BitSet) {
        def isSet(mode: OpMode) = bits.contains(mode.mask)
        def +(mode: OpMode) = new FlagSet(bits + mode.mask)
        def -(mode: OpMode) = new FlagSet(bits - mode.mask)
        def &(other: FlagSet) = new FlagSet(bits & other.bits)
        def &~(other: FlagSet) = new FlagSet(bits &~ other.bits)
        def ^(other: FlagSet) = new FlagSet(bits ^ other.bits)
        def |(other: FlagSet) = new FlagSet(bits | other.bits)
        def size = bits.size
        // etc.
    
      }
    
      object FlagSet {
        def apply(flags: OpMode*): FlagSet = apply(BitSet(flags.map(_.mask):_*))
        def apply(modes: ValueSet): FlagSet = apply(BitSet(modes.toSeq.map{ case m: OpMode => m.mask }:_*))
      }
    
    }
    
    def doSomethingSmarter(modes: OpMode.FlagSet, someGoodyList: List[Any]) = modes.size
    
    val flags = OpMode.FlagSet(OpMode.Read, OpMode.Write)
    
    doSomethingSmarter(flags, Nil)
    
    val modes = OpMode.ValueSet(OpMode.Read, OpMode.Write)
    
    doSomethingSmarter(OpMode.FlagSet(modes), Nil)
    
    基本上,我扩展了枚举.Val类型,为每个模式添加了一个合适的位掩码,并添加了一个内部类
    FlagSet
    ,以便在操作模式和隐藏位集之间进行互操作。将doSomethingSmarter更改为接受这样一个标记集可以使使用更接近您所希望的


    上述内容可能会有所改进,但使用枚举可能会比较棘手。作为替代方案,您可能会发现使用密封的trait和扩展它的case类/对象更可取-这通常会使语义更接近Java的枚举类型。

    这可能包含一些可能性。(我更新了这个问题,让它更清楚一点。希望如此)您是说将方法参数键入“opMode:Enumeration[opMode]”还是说,将其键入一个集合[opMode],然后传入从外部定义的枚举中提取的集合?(请原谅,这不是正确的Scala ese,因为我还在学习该语言。)(我认为这将提供比列表更快的查找速度,特别是如果使用RB集的话。)@mjk否,您可以将方法参数键入Opmode.ValueSet。或者您可以使用我对答案所做的编辑。很好!这让我更好地了解Scala内置的边界。谢谢。