사실,이 성능 버그 2.11에서 해결되었습니다
$ skala
Welcome to Scala version 2.11.0-20130423-194141-5ec9dbd6a9 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_06).
Type in expressions to have them evaluated.
Type :help for more information.
scala> val data = List("a","b","c","d","e")
data: List[String] = List(a, b, c, d, e)
scala>
scala> object Uap {
| def unapply(s:String) = {
| println("S: "+s)
| Some(s+"!")
| }
| }
defined object Uap
scala>
scala> println(data.collect{ case Uap(x) => x })
S: a
S: b
S: c
S: d
S: e
List(a!, b!, c!, d!, e!)
이
applyOrElse에 효율성 노트를 참조하십시오. 여기
이 문제를 쉽게 확장하여 구제되어 2.10 대한 버전이다 :
object Test extends App {
import scala.collection.TraversableLike
import scala.collection.generic.CanBuildFrom
import scala.collection.immutable.StringLike
implicit class Collector[A, Repr, C <: TraversableLike[A, Repr]](val c: C) extends AnyVal {
def collecting[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(c.repr)
c.foreach(pf.runWith(b += _))
b.result
}
}
val data = List("a","b","c","d","e")
object Uap {
def unapply(s:String) = {
println("S: "+s)
s match {
case "foo" => None
case _ => Some(s+"!")
}
}
}
val c = Collector[String, List[String], List[String]](data)
Console println c.collecting { case Uap(x) => x }
}
결과 : UAP이 버전의 부분임을
$ scalac -version
Scala compiler version 2.10.1 -- Copyright 2002-2013, LAMP/EPFL
[email protected] ~/tmp
$ scalac applyorelse.scala ; scala applyorelse.Test
S: a
S: b
S: c
S: d
S: e
List(a!, b!, c!, d!, e!)
참고
scala> val data = List("a","b","c","d","e", "foo")
data: List[String] = List(a, b, c, d, e, foo)
scala> data.map{ case Uap(x) => x }
S: a
S: b
S: c
S: d
S: e
S: foo
scala.MatchError: foo (of class java.lang.String)
유스 케이스가 PF 인 경우 코드가 부분적이어야한다고 생각합니다.
이
def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That = {
val b = bf(repr)
for (x <- this) if (pf.isDefinedAt(x)) b += pf(x)
b.result
}
그것은 pf.isDefinedAt(x)
을 사용으로 @stew 대답에 추가
또 다른 옵션은 부분 함수 오브젝트의 마지막 값을 캐시하는 것입니다. – ziggystar
@ 그렉 이것은 사실이지만, 올드 스쿨의 일종으로, 2.11에서는 사실이 아니고 2.10에서 다소 괜찮은 수정을 가졌습니다. –