2012-02-22 1 views
3

먼저. 다음 코드를 고려하십시오.scalac이 추가/포장 마감을 생성하는 이유

scala> val fail = (x: Any) => { throw new RuntimeException } 
fail: Any => Nothing = <function1> 

scala> List(1).foreach(fail) 
java.lang.RuntimeException 
    at $anonfun$1.apply(<console>:7) 
    at $anonfun$1.apply(<console>:7) 
    at scala.collection.LinearSeqOptimized$class.foreach(LinearSeqOptimized.scala:59) 

foreach와 예외 사이에는 추가 anonfun이 있습니다. 하나는 fail 자체의 값 (Function1 [])의 개체가 될 것으로 예상되지만 두 번째 값은 어디에서 오는 것입니까? 그래서

def foreach[U](f: A => U): Unit 

, 두 번째의 목적은 무엇인가 :

foreach 서명은이 기능을한다? 그들이 정말 필요합니까 ... 두 개의 추가 anonfuns 있습니다

scala> def outer() { 
    | def innerFail(x: Any) = { throw new RuntimeException("inner fail") } 
    | 
    | Set(1) foreach innerFail 
    | } 
outer:()Unit 

scala> outer() 
java.lang.RuntimeException: inner fail 
    at .innerFail$1(<console>:8) 
    at $anonfun$outer$1.apply(<console>:10) 
    at $anonfun$outer$1.apply(<console>:10) 
    at scala.collection.immutable.Set$Set1.foreach(Set.scala:86) 

:

둘째, 다음 코드를 고려? : -E

+0

스칼라 버전 2.9.2.rdev-2769-2011-12-13-g2dd83da (Java HotSpot (TM) 64 비트 서버 VM, Java 1.6.0_25). – tuxSlayer

답변

4

바이트 코드를 살펴 보겠습니다.

public final scala.runtime.Nothing$ apply(java.lang.Object); 
    Code: 
    0: new #15; //class java/lang/RuntimeException 
    3: dup 
    4: invokespecial #19; //Method java/lang/RuntimeException."<init>":()V 
    7: athrow 

public final java.lang.Object apply(java.lang.Object); 
    Code: 
    0: aload_0 
    1: aload_1 
    2: invokevirtual #27; //Method apply:(Ljava/lang/Object;)Lscala/runtime/Nothing$; 
    5: athrow 

이 그래서 결국 실제로 추가 폐쇄 아니다 :

object ExtraClosure { 
    val fail = (x: Any) => { throw new RuntimeException } 
    List(1).foreach(fail) 
} 

우리는 (하나의) 익명 함수 내부에서 찾을 수 있습니다. 두 개의 다른 반환 값으로 오버로드 된 하나의 메소드가 있습니다 (JVM이 함수 서명의 일부로 모든 매개 변수의 유형을 처리하므로 완벽하게 괜찮습니다). 함수는 일반적이므로 객체 반환을 가져야하지만 작성한 코드는 특별히 Nothing을 반환하며 예상 한 유형을 반환하는 메서드도 만듭니다.

여기에는 여러 가지 방법이 있지만 결함이없는 것은 없습니다. 그러나 이것은 JVM이 매우 잘하는 유형이기 때문에 걱정하지 않을 것입니다.

편집 : 물론 두 번째 예에서는 def을 사용했으며 anonfundef을 함수 객체로 래핑하는 클래스입니다. foreachFunction1이므로 필요합니다. 어떻게 든 Function1을 생성해야합니다.

+0

아 ... 알았어요. 그러나 (f : A => Any)를 'foreach()'의 매개 변수로 사용하여 생성을 피하는 것이 더 좋지 않을까요? – tuxSlayer

+0

@tuxSlayer - 여전히 그럴 수 없습니다. 'A => Any'는 이미 사용중인 Object => Object로 지워집니다. –

+0

아 ... :) 그것을 얻으십시오 – tuxSlayer

관련 문제