2013-02-01 26 views
1

有一种简洁的方式来检查表达式是否与给定的模式匹配?例如,请考虑以下代码:简洁的方式来检查表达式是否与Scala中的模式匹配

val result = expr match { 
    SomePattern(_, 1, _) => true 
    _ => false 
} 

尽管此代码有效,但它相当噪音且很长。我想知道是否有更好的方法来达到同样的效果。这将是巨大的,如果斯卡拉有matches结构,这将允许一个写

val result = expr matches SomePattern(_, 1, _) 

我甚至会考虑写一个辅助功能,使可能沿着这些线路的东西。但是,这似乎很难做到,因为据我所知,我无法通过一种模式作为论据。也许像这样的事情可能在Scala 2.10中可用的宏(作为实验性功能)?

+0

噢,是的,Paul Phillips对链接问题的回答可能是最好的你会得到:) – 2013-02-01 15:09:07

回答

0

match构造允许的完全相同的语法可用于将PartialFunction写为函数文字。但编译器必须知道这是必需的。换句话说,它需要的东西来驱动类型推断:

scala> val pf1 = { case i: Int if i % 2 == 0 => true; case i: Int => false } 
<console>:42: error: missing parameter type for expanded function 
The argument types of an anonymous function must be fully known. (SLS 8.5) 
Expected type was: ? 
     val pf1 = { case i: Int if i % 2 == 0 => true; case i: Int => false } 
       ^

scala> val pf2: Function[Int, Boolean] = { case i: Int if i % 2 == 0 => true; case _ => false } 
<console>:42: error: $r.intp.global.Function does not take type parameters 
     val pf2: Function[Int, Boolean] = { case i: Int if i % 2 == 0 => true; case _=> false } 
       ^
<console>:42: error: missing parameter type for expanded function 
The argument types of an anonymous function must be fully known. (SLS 8.5) 
Expected type was: <error> 
     val pf2: Function[Int, Boolean] = { case i: Int if i % 2 == 0 => true; case _=> false } 
             ^

scala> val pf3: PartialFunction[Int, Boolean] = { case i: Int if i % 2 == 0 => true; case _ => false } 
pf3: PartialFunction[Int,Boolean] = <function1> 
1

你可以定义一个函数“匹配”,做类似的东西,如:

scala> def matches[A](a: A)(f: PartialFunction[A, Unit]) = f isDefinedAt a 
matches: [A](a: A)(f: PartialFunction[A,Unit])Boolean 

scala> matches("abc") { case "abc" =>() } 
res0: Boolean = true 

scala> matches("abc") { case "x" =>() } 
res1: Boolean = false 
2
scala> import PartialFunction.cond 
import PartialFunction.cond 

scala> cond(Option(2)) { case Some(2) => true } 
res0: Boolean = true 

scala> cond(Option(3)) { case Some(2) => true } 
res1: Boolean = false 

这么说,我支持“匹配”在过去,尽管有很多方法称为。

+0

这当然是好的,它在标准库中。但是,键入有点限制,因为下面的代码不会编译:'cond(None){case Some(_)=> true}'。它失败,'构造函数不能实例化到预期的类型。发现:一些[A],要求:None.type'。 –

+0

这就是为什么“一些”和“无”应该是方法(如斯卡拉茨,iirc) – 2013-02-01 15:47:43

+0

@RégisJean-Gilles,但这将:'cond(None:Option [_]){case Some(_)=> true} '。只是说它不是太严格,因为大多数时候(我实际上不能考虑其他情况),你想匹配具有选项类型的值。 –

相关问题