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内置的边界。谢谢。