scala - 是否可以从 self 类型调用重写的方法?

标签 scala

考虑一下:

 class Foo { def foo = "foo" }
 trait Bar { self: Foo =>
    override def foo = "bar"
 }

我惊喜地发现这是可能的,并且按预期工作:
new Foo with Bar foo 

返回“酒吧”。问题是 Bar.foo 是否可行调用 Foo.foo ,就像在“普通”继承案例中经常做的那样。 override def foo = super.foo + "bar"不起作用(说“foo 不是 AnyRef 的成员),override def foo = self.foo + "bar" 也不起作用(它最终只是调用自己,并导致无限递归)。
我尝试了其他一些组合(如 self.Foo.fooFoo.this.foo 等),但没有任何运气。

这是不可能的吗?

最佳答案

不。不可能从 self 类型调用重写的方法。

首先是特质Bar不是类 Foo 的继承者所以不可能使用 super.foo .

其次,也不能使用 self.fooself实际上是类型 Bar with Foo .可以通过在typer后面打印程序来显示:

$ scalac -Xprint:typer test.scala
[[syntax trees at end of                     typer]] // test.scala
package <empty> {
  class Foo extends scala.AnyRef {
    def <init>(): Foo = {
      Foo.super.<init>();
      ()
    };
    def foo: String = "foo"
  };
  abstract trait Bar extends scala.AnyRef { self: Bar with Foo => 
    def /*Bar*/$init$(): Unit = {
      ()
    };
    override def foo: String = "bar"
  };
  class FooBar extends Foo with Bar {
    def <init>(): FooBar = {
      FooBar.super.<init>();
      ()
    }
  };
  object TestApp extends scala.AnyRef {
    def <init>(): TestApp.type = {
      TestApp.super.<init>();
      ()
    };
    def main(args: Array[String]): Unit = {
      val a: FooBar = new FooBar();
      scala.this.Predef.println(a.foo)
    }
  }
}

所以与 self.foo您正在尝试访问该方法 foo性状 Bar .此类行为符合 Scala Specification (PDF):

The sequence of template statements may be prefixed with a formal parameter definition and an arrow, e.g. x =>, or x: T =>. If a formal parameter is given, it can be used as an alias for the reference this throughout the body of the template. If the formal parameter comes with a type T, this definition affects the self type S of the underlying class or object as follows: Let C be the type of the class or trait or object defining the template. If a type T is given for the formal self parameter, S is the greatest lower bound of T and C. If no type T is given, S is just C. Inside the template, the type of this is assumed to be S.



可以使用反射访问该方法,但我认为这不是您想要的。

关于scala - 是否可以从 self 类型调用重写的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36945333/

相关文章:

java - 使用 Datastax Java 驱动程序返回 JSON

scala - 在 ScalaCheck 中生成任意线性函数?

scala - Scala 中的 WebDriver 显式等待

Scala:Cats、OptionT[Future, T] 和 ApplicativeError

scala - 由于类型不匹配(单元和字符串),不能像这样在 reduce 中打印?

scala - Scala 中是否有维护的不可变优先级队列?

scala - 如何在 Scala 中使用 POJO 等效项?

postgresql - 使用 Slick 执行并发查询时出现 NullPointerException

scala - Lift Mapper 中的 LowerCase Like 语句

scala - 异常 joda-time - localdatetime 支持