الدالة الافتراضية الدالة المعلمة المعلمة الفئة الحرفية
-
21-09-2019 - |
سؤال
هل هذا سلوك مقصود أم أنه خطأ؟ النظر في السمة التالية (سواء كانت فئة ، لا يهم):
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} = $anon$1@12192a9
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() {
^
المحلول
يبدو أن هذا خطأ ، وإن كان ذلك عند تقاطع غامض إلى حد ما بين الطبقات المتداخلة ، وأنواع التجريد ، والمعلمات الافتراضية. يمكنك رفع تذكرة في سكالا تعقب الأخطاء - لم أتمكن من العثور على تذكرة موجودة تصف هذا.
إليكم كيف يبدو أن مرحلة Typer:
~: 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();
()
}
}
}
}
}
لا تنتمي إلى StackOverflow