Scala의 패턴 일치는 바이트 코드 수준에서 어떻게 구현됩니까?
일련의 if (x instanceof Foo)
구조와 같습니까, 아니면 다른 것입니까? 성능에 미치는 영향은 무엇입니까?
예를 들어, 다음 코드 ( Scala By Example 페이지 46-48)가 주어지면 eval
메서드에 해당하는 Java 코드는 어떻게 생겼습니까?
abstract class Expr
case class Number(n: Int) extends Expr
case class Sum(e1: Expr, e2: Expr) extends Expr
def eval(e: Expr): Int = e match {
case Number(x) => x
case Sum(l, r) => eval(l) + eval(r)
}
추신 : Java 바이트 코드를 읽을 수 있으므로 바이트 코드 표현만으로도 충분하지만 다른 독자가 Java 코드로 어떻게 생겼는지 아는 것이 더 나을 것입니다.
PPS Programming in Scala 책 은 Scala가 어떻게 구현되는지에 대한 이와 유사한 질문에 대한 답을 제공합니까? 책을 주문했지만 아직 도착하지 않았습니다.
답변
낮은 수준은 디스어셈블러로 탐색 할 수 있지만 짧은 대답은 술어가 패턴에 따라 달라지는 if / elses의 무리라는 것입니다.
case Sum(l,r) // instance of check followed by fetching the two arguments and assigning to two variables l and r but see below about custom extractors
case "hello" // equality check
case _ : Foo // instance of check
case x => // assignment to a fresh variable
case _ => // do nothing, this is the tail else on the if/else
“case Foo (45, x)”와 같은 패턴이나 패턴과 조합으로 할 수있는 것이 훨씬 더 많지만 일반적으로 그것들은 방금 설명한 것의 논리적 확장 일뿐입니다. 패턴은 또한 술어에 대한 추가 제한 조건 인 가드를 가질 수 있습니다. 또한 컴파일러가 패턴 일치를 최적화 할 수있는 경우도 있습니다. 예를 들어 케이스간에 겹치는 부분이있는 경우 약간 합쳐질 수 있습니다. 고급 패턴 및 최적화는 컴파일러에서 작업의 활성 영역이므로 현재 및 향후 버전의 Scala에서 이러한 기본 규칙보다 바이트 코드가 크게 향상 되더라도 놀라지 마십시오.
이 모든 것 외에도 Scala가 케이스 클래스에 사용하는 기본 추출기에 추가하거나 대신 사용자 지정 추출기를 작성할 수 있습니다. 그럴 경우 패턴 일치 비용은 추출기가 수행하는 작업의 비용입니다. http://lamp.epfl.ch/~emir/written/MatchingObjectsWithPatterns-TR.pdf에 좋은 개요가 있습니다.
답변
James (위)가 가장 잘 말했습니다. 그러나 궁금하다면 디스 어셈블 된 바이트 코드를 보는 것이 항상 좋은 연습입니다. 옵션을 scalac
사용하여 호출 할 수도 있습니다. 그러면 -print
모든 Scala 관련 기능이 제거 된 프로그램이 인쇄됩니다. 기본적으로 Scala의 옷에서 Java입니다. scalac -print
제공 한 코드 스 니펫에 대한 관련 출력은 다음과 같습니다 .
def eval(e: Expr): Int = {
<synthetic> val temp10: Expr = e;
if (temp10.$isInstanceOf[Number]())
temp10.$asInstanceOf[Number]().n()
else
if (temp10.$isInstanceOf[Sum]())
{
<synthetic> val temp13: Sum = temp10.$asInstanceOf[Sum]();
Main.this.eval(temp13.e1()).+(Main.this.eval(temp13.e2()))
}
else
throw new MatchError(temp10)
};
답변
버전 2.8부터 Scala에는 @switch 주석이 있습니다. 목표는 패턴 일치가 일련의 조건문 대신 테이블 스위치 또는 조회 스위치 로 컴파일되도록하는 것 if
입니다.