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

How to resolve self reference in this case?

对于这两个代码块,我预计两个代码块中的 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))
    }
  }
}

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

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

在第二个片段中,您说 Foo[A] 类型的对象有一个名为 self 的成员字段并被分配 this。这将适用于 Foo[_] 的所有实例,无论您如何调用类型参数。当您创建第二个 Foo 调用类型参数 B 时,第二个实例仍然会有一个成员字段 self,它被分配 this,此时是 Foo[B]shades 您在 Foo.

的初始声明中声明的 self

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

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

对于令人费解的回复,我们深表歉意;简而言之:类型参数只是实际类型的占位符名称,就像值参数是实际运行时值的占位符名称一样。对类型和值应用相同的推理,关于它们的推理将变得更容易。