我经常编写比较两个对象的代码,并根据它们是否相同或不同(根据它们的不同之处)生成一个值。
所以我可能会写:
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case (Some(value), None)) => "b"
case (None, Some(value)) => "b"
case _ = > "c"
}
第二个和第三个案例实际上是相同的,所以我尝试写:
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case (Some(value), None)) || (None, Some(value)) => "b"
case _ = > "c"
}
但没有运气。
我在几个地方遇到这个问题,这只是一个具体的例子,更一般的模式是我有两件事,我想知道其中是否只有一个满足某个谓词,所以我想写像这样的东西:
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case OneAndOnlyOne(value, v: Option[Foo] => v.isDefined ) => "b"
case _ = > "c"
}
所以这里的想法是 OneAndOnlyAve 可以配置一个谓词(在本例中是 Defined ),并且您可以在多个地方使用它。
上面的代码根本不起作用,因为它是向后的,谓词需要传递到提取器中而不是返回。
像这样的事情怎么样?
val result = (v1,v2) match {
case (Some(value1), Some(value2)) => "a"
case new OneAndOnlyOne(v: Option[Foo] => v.isDefined )(value) => "b"
case _ = > "c"
}
with:
class OneAndOnlyOne[T](predicate: T => Boolean) {
def unapply( pair: Pair[T,T] ): Option[T] = {
val (item1,item2) = pair
val v1 = predicate(item1)
val v2 = predicate(item2)
if ( v1 != v2 )
Some( if ( v1 ) item1 else item2 )
else
None
}
}
但是,这不能编译。
任何人都可以找到使该解决方案发挥作用的方法吗?或者提出另一种解决方案?我可能让这件事变得更加复杂:)