2010-03-23 9 views
2

의도 한 동작입니까, 아니면 버그입니까? (이 클래스, 중요하지 않습니다 수) 다음과 같은 특성을 고려기본 유형 매개 변수 리터럴 클래스 매개 변수

scala> val p = new P[Int] { 
    |  val inner = new Inner 
    | } 
p: java.lang.Object with P[Int]{def inner: this.Inner} = [email protected] 

scala> p.inner.f(5) 
nope 

그러나이 : ​​

trait P[T] { 
    class Inner(val f: T => Unit = _ => println("nope")) 
} 

이것은 내가 기대 한 것이 무엇인가?

중첩 된 클래스, 추상 유형 및 기본 매개 변수 사이의 다소 모호한 교차로에 불구하고, 버그가 나타납니다
scala> val p = new P[Int] { 
    |  val inner = new Inner() { 
    |   println("some primary constructor code in here") 
    |  } 
    | } 
<console>:6: error: type mismatch; 
found : (T) => Unit 
required: (Int) => Unit 
      val inner = new Inner() { 
         ^
+0

그래서 버그 였고 약 2 주 전에 수정되었습니다. –

답변

2

. Scala에서 티켓을 올릴 수 있습니다 bug tracker - 이것을 설명하는 기존 티켓을 찾을 수 없습니다.

여기가 타이 퍼 단계 이후 보이는 방법은 다음과 같습니다

~: scala -nocompdaemon -Xprint:typer -e 'trait P[T] { class Inner(val f: T = null.asInstanceOf[T]) }; new P[Int] { new Inner(){} }' 
!!! 
discarding <script preamble> 
(fragment of scalacmd162105603941759154.scala):1: error: type mismatch; 
found : T 
required: Int 
trait P[T] { class Inner(val f: T = null.asInstanceOf[T]) }; new P[Int] { new Inner(){} } 
                      ^
[[syntax trees at end of typer]]// Scala source: (virtual file) 
package <empty> { 
    final object Main extends java.lang.Object with ScalaObject { 
    def this(): object Main = { 
     Main.super.this(); 
    () 
    }; 
    def main(argv: Array[String]): Unit = { 
     val args: Array[String] = argv; 
     { 
     final class $anon extends scala.AnyRef { 
      def this(): anonymous class $anon = { 
      $anon.super.this(); 
      () 
      }; 
      abstract trait P[T >: Nothing <: Any] extends java.lang.Object with ScalaObject { 
      def /*P*/$init$(): Unit = { 
      () 
      }; 
      class Inner extends java.lang.Object with ScalaObject { 
       <paramaccessor> private[this] val f: T = _; 
       <stable> <accessor> <paramaccessor> def f: T = Inner.this.f; 
       def this(f: T = null.asInstanceOf[T]): P.this.Inner = { 
       Inner.super.this(); 
       () 
       } 
      }; 
      final <synthetic> object Inner extends java.lang.Object with ScalaObject { 
       <synthetic> def init$default$1: T @scala.annotation.unchecked.uncheckedVariance = null.asInstanceOf[T]; 
       def this(): object P.this.Inner = { 
       Inner.super.this(); 
       () 
       } 
      } 
      }; 
      { 
      final class $anon extends java.lang.Object with this.P[Int] { 
       def this(): anonymous class $anon = { 
       $anon.super.this(); 
       () 
       }; 
       { 
       final class $anon extends $anon.this.Inner { 
        def this(): anonymous class $anon = { 
        $anon.super.this(P.this.Inner.<error: method init$default$1>); 
        () 
        }; 
        <empty> 
       }; 
       new $anon() 
       } 
      }; 
      new $anon() 
      } 
     }; 
     { 
      new $anon(); 
     () 
     } 
     } 
    } 
    } 
} 

그리고 작업 버전을, 내부 확장 익명의 내부 클래스없이.

~: scala -nocompdaemon -Xprint:typer -e 'trait P[T] { class Inner(val f: T = null.asInstanceOf[T]) }; new P[Int] { new Inner() }' 
[[syntax trees at end of typer]]// Scala source: (virtual file) 
package <empty> { 
    final object Main extends java.lang.Object with ScalaObject { 
    def this(): object Main = { 
     Main.super.this(); 
    () 
    }; 
    def main(argv: Array[String]): Unit = { 
     val args: Array[String] = argv; 
     { 
     final class $anon extends scala.AnyRef { 
      def this(): anonymous class $anon = { 
      $anon.super.this(); 
      () 
      }; 
      abstract trait P[T >: Nothing <: Any] extends java.lang.Object with ScalaObject { 
      def /*P*/$init$(): Unit = { 
      () 
      }; 
      class Inner extends java.lang.Object with ScalaObject { 
       <paramaccessor> private[this] val f: T = _; 
       <stable> <accessor> <paramaccessor> def f: T = Inner.this.f; 
       def this(f: T = null.asInstanceOf[T]): P.this.Inner = { 
       Inner.super.this(); 
       () 
       } 
      }; 
      final <synthetic> object Inner extends java.lang.Object with ScalaObject { 
       <synthetic> def init$default$1: T @scala.annotation.unchecked.uncheckedVariance = null.asInstanceOf[T]; 
       def this(): object P.this.Inner = { 
       Inner.super.this(); 
       () 
       } 
      } 
      }; 
      { 
      final class $anon extends java.lang.Object with this.P[Int] { 
       def this(): anonymous class $anon = { 
       $anon.super.this(); 
       () 
       }; 
       new $anon.this.Inner($anon.this.Inner.init$default$1) 
      }; 
      new $anon() 
      } 
     }; 
     { 
      new $anon(); 
     () 
     } 
     } 
    } 
    } 
}