我有instance.get返回值的代码,并根据类型I进行相应处理.
instance.get match {
case v:Range => {
val sizeInBytes = util.conversion.Util.getBytesForBits(v.size)
val value = v.decode(contentByteArray.slice(index, index + sizeInBytes))
index += sizeInBytes
res(key) = value
}
case v:Encoding => {
val sizeInBytes = util.conversion.Util.getBytesForBits(v.size)
val value = v.decode(contentByteArray.slice(index, index + sizeInBytes))
index += sizeInBytes
res(key) = value
}
...
}
Run Code Online (Sandbox Code Playgroud)
在代码中,我有Range和Encoding类型的重复.我如何合并这两个案例?
我尝试了|操作员,但它不起作用.
case v:Range | v:Encoding
Run Code Online (Sandbox Code Playgroud)
这可不行,因为Range.size和Encoding.size是尽管它们被命名为相同的两个完全不同的方法.同样适用于Range.decode和Edncoding.decode.
所以,当你写作时v.size,v必须知道它的类型,它必须是v:Encoding或者v:Range不是v:Encoding|v:Range.
如何解决这个问题?做一个像这样的共同特征:
trait SomethingWithDecodeAndSize {
def size: Int
def decode(bytes: Array[Byte]): Whatever
}
Run Code Online (Sandbox Code Playgroud)
然后,改变的定义Range和Encoding:
class Range extends SomethingWithDecodeAndSize { ... }
class Encoding extends SomethingWithDecodeAndSize { ... }
Run Code Online (Sandbox Code Playgroud)
现在你可以case v: SomethingWithDecodeAndSize => ...在你的匹配条款中做.
还有......不要这样做instance.get,那味道不好.相反
instance match {
Some(v: SomethingWithDecodeAndSize) => ...
}
Run Code Online (Sandbox Code Playgroud)
更新 如果无法修改原始类的定义,则可以使用提取器:
object SomethingWithDecodeAndSize {
def unapply(a: Any): Option[SomethingWithDecodeAndSize] = a match {
case r: Range => Some(new SomethingWithDecodeAndSize {
def size = r.size
def decode(bytes: Array[Byte]) = r.decode(bytes)
})
case r: Encoding => Some(new SomethingWithDecodeAndSize {
def size = r.size
def decode(bytes: Array[Byte]) = r.decode(bytes)
})
case _ => None
}
}
Run Code Online (Sandbox Code Playgroud)
现在,你可以case Some(SomethingWithDecodeAndSize(v)) => ...在你的比赛中做到.