在这种情况下如何解决自我引用?

时间:2017-01-30 12:13:15

标签: scala this self

对于这两个代码块,我希望两个块中的self引用都是Foo [A]。但是似乎第二个块没有编译。有人可以向我解释如何解决self引用吗?

trait Foo[A] {
  def format(value:A):String
  def bar[B](f:B=>A):Foo[B] = {
    val self = this
    new Foo[B] {
      override def format(value: B): String = self.format(f(value))
    }
  }
}

trait Foo[A] {
  def format(value:A):String
  val self = this
  def bar[B](f:B=>A):Foo[B] = {      
    new Foo[B] {
      override def format(value: B): String = self.format(f(value))
    }
  }
}

1 个答案:

答案 0 :(得分:2)

self被赋予this,这是对特定实例的引用,是您在调用时调用方法(或构造函数)的实例。

在第一个代码段中,您在bar类型的对象上调用方法Foo[A],这意味着此时this表示Foo[A]的实例。在将this分配给self之后,您将继续创建Foo的新实例,这次为type参数指定了不同的类型,但self

在第二个代码段中,您说类型Foo[A]的对象有一个名为self的成员字段,并被分配this。无论您如何调用type参数,这都将适用于Foo[_]的所有实例。当您创建第二个Foo调用类型参数B时,第二个实例仍会有一个成员字段self,该字段将被分配this,此时此字段为{ {1}}和阴影您在Foo[B]的初始声明中声明的self

这意味着在第二个代码段中,Foo format方法实现可以访问Foo[B]本身的self引用,这会导致类型错误提及。

  • Foo [B]有方法格式(值:B)
  • 方法Foo[B]采用一个bar并将其转换为B
  • 的函数
  • 您将A应用于f: B => A,将其变为value: B,然后尝试将A提供给A

对于错综复杂的回复感到抱歉;简而言之:类型参数仅仅是实际类型的占位符名称,就像值参数是实际运行时值的占位符名称一样。将相同的推理应用于类型和值,并且对它们的推理将变得更容易。