Scala:类型模式匹配的简写?

时间:2015-03-10 12:18:20

标签: scala

是否有更优雅的方式来执行以下操作?

data match {
  case e: SomeType => doSomethingWith(e)
  case _ =>
}

寻找类似的东西:

data.ifInstanceOf[SomeType](doSomethingWith)

5 个答案:

答案 0 :(得分:4)

您想要一个表达式还是只是执行副作用?如果只是副作用通过" PimpMyLibrary"方法+反思:

  import scala.reflect.ClassTag

  implicit class AnyOps(data : Any) {
     def ifInstanceOf[A : ClassTag](f: A => Unit) : Unit = {
        val clzz = implicitly[ClassTag[A]].runtimeClass
        if (clzz.isInstance(data)) f(data.asInstanceOf[A])      
     }
  }

然后您可以尝试

"abc".ifInstanceOf[String](println)
"def".ifInstanceOf[Integer](println)
1.ifInstanceOf[Integer](println)
2.ifInstanceOf[String](println)

如果你想要一个表达式,我认为最好的方法是添加一个额外的类型参数B并返回[B,Anyref]。

答案 1 :(得分:4)

我认为collect可能对此有用。该方法采用部分函数,​​并过滤掉与任何case语句不匹配的元素:

Option(data) collect {
    case element: SomeType => mappingFunction(element)
}

当然,此处mappingFunction可能会产生副作用并返回Unit,从而模仿foreach

如果您想创建一个新的命名方法,可以在Any上创建一个新方法:

implicit class AnyOps(data: Any) {
    def forMatch[A](pf: PartialFunction[Any, A]) = pf.lift(data)
}

答案 2 :(得分:3)

出于某种原因,这没有出现:

import PartialFunction._

condOpt("abc": Any) { case s: String => s.length } // = Some(3)
condOpt((): Any) { case s: String => s.length } // = None

我通常将其或其兄弟cond重命名为when

答案 3 :(得分:1)

您可以使用asInstanceOf来实现目标:

Option(data)
  .filter(_.isInstanceOf[SomeType])
  .map(_.asInstanceOf[SomeType])
  .map(doSomethingWith)

但我觉得它太冗长了。

答案 4 :(得分:0)

我认为你会发现很难找到更短或更精确的东西而不是#34;好老" ......

if (data.isInstanceOf[SomeType]) doSomething(data)

...除非你的案子比你显示的更复杂