2010-03-23 105 views
2

這是一個預期的行爲,或者它是一個錯誤?請看下面的特徵(可能是一個類,無所謂):默認的類型 - 參數化函數文字類參數

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

這是我本來期望:

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 

但這?

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

所以這是一個錯誤,它在兩個星期前被糾正了。 – 2010-04-20 12:02:02

回答

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(); 
     () 
     } 
     } 
    } 
    } 
}