scala - 名为 Scala 自类型仍然阴影 "this"?

标签 scala traits self-type

工作通过 these posts让我认为我了解自我类型,至少在某种程度上。

所以我创建了一个按预期失败的例子:

scala> trait A { val v = "a" }
defined trait A

scala> trait B { this :A => ; var v = "" ; this.v = "b" }
<console>:6: error: reassignment to val
       trait B { this :A => ; var v = "" ; this.v = "b" }
                                                  ^

自我类型的“这个”阴影 B 的“这个”——看起来很奇怪,但有道理。

那么,给自我类型一个不同的名字似乎是明智的。我这样做了,而且相当惊讶:
scala> trait C { a :A => ; var v = "" ; this.v = "c" }
<console>:6: error: reassignment to val
       trait C { a :A => ; var v = "" ; this.v = "c" }
                                               ^

还是有阴影???

更改“本地”变量的名称让事情编译,这是有道理的:
scala> trait D { a :A => ; var w = "" ; this.w = a.v }
defined trait D

(并且可以选择使用自类型名称来阐明要使用的“v”。)

好的。这意味着以下应该失败?
scala> trait E { this :A => ; var w = "" ; this.w = this.v }
defined trait E

嗯?这是哪个? :-(

那么......命名自我类型有什么意义吗?不管怎样,“这个”似乎最终都被遮蔽了。

或者这是范围规则的边缘情况,其中自我类型的“this”优先于特征的“this”——并且应该避免对相关特征中的事物使用相同的名称?

最佳答案

您的问题不是 self 类型的名称(在您的所有示例中, this 和备用 self-type 名称都指代完全相同的事物并且具有相同的类型,即“BA 的最大下限”[§5.1] , Scala Language Spec]) 但您尝试再次定义具有相同名称的字段而不显式覆盖它。

看一个更简单的例子:

trait A { val v = "a" }
trait B { this: A =>
  var v = "b"
}

new A with B {} // does not compile

<console>:9: error: overriding value v in trait A$class of type java.lang.String;
 variable v in trait B$class of type java.lang.String needs `override' modifier
   new A with B {}

因此,即使您在定义 B 时不会出错,但无论如何您根本无法使用它。

这会工作
trait A { val v = "a" }
trait B { this:A => override val v = "b"  }

new A with B {}

在这里,您在 A 中明确覆盖了 vB 。 (注意 new B with A {} 会失败,因为 B 需要放在最后。)此外,它必须是 val 因为在大多数情况下你不能真正覆盖 var 并且你不能使用 var 覆盖其他东西

通常,在这些简单的情况下,您不应该关心自类型的名称。只要您不在 B 内创建另一个特征或类, this 和您称之为 self 类型变量的任何东西都将指向同一事物。不会有阴影。如果您在 B 中有一个新特征,并且您需要在该特征中引用 B 的实例,则您的 self 类型需要另一个名称。

考虑这个
trait B { this =>
  val v = "b"
  trait C {
    val v = "c"
    println(this.v)
  }
  new C {}
}
new B {}

// prints c

与这个:
trait B { self =>
  val v = "b"
  trait C {
    val v = "c"
    println(this.v)  // prints c
    println(self.v)  // prints b
  }
  new C {}
}
new B {}

(在没有任何进一步类型注释的情况下,您可以省略本示例中的所有 this。)

关于scala - 名为 Scala 自类型仍然阴影 "this"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4741724/

相关文章:

scala - 带有 Window orderBy 表达式的最后一个函数未按预期工作

php - 为什么 trait 不覆盖类中的方法?

scala - self 类型和特质子类有什么区别?

scala - 使代码更具功能可读性

scala - Akka 集群中的 Actor 查找

scala - Scala-可选参数,无需用户输入Some(…)

scala - 有没有办法从 Scala 中的实例中删除特征?

c++ - 使用弃用的绑定(bind)器和 C++0x lambda

Scala自类型注释与 'with'混合

Scala:父类是否可以访问仅由子级定义的方法?