gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-03 03:57:17 25 4
gpt4 key购买 nike

特征的 self 类型A:

trait B
trait A { this: B => }

A不能混合到不扩展B的具体类中”

另一方面,以下内容:

trait B
trait A extends B

“在A中混合的任何(具体或抽象)类也将在B中混合”

这两个说法不是同一个意思吗? self 类型似乎只是为了产生简单的编译时错误的可能性。

我错过了什么?

最佳答案

主要用于 Dependency Injection ,例如在蛋糕图案中。存在 great article涵盖了 Scala 中许多不同形式的依赖注入(inject),包括 Cake 模式。如果你用谷歌搜索“Cake Pattern and Scala”,你会得到很多链接,包括演示文稿和视频。现在,这里是 another question 的链接.

现在,至于 self 类型和扩展特质之间有什么区别,这很简单。如果您说B extends A,那么B一个A。当您使用自类型时,B 需要 A。使用 self 类型创建有两个特定要求:

  1. 如果扩展了 B,那么您需要混入 A
  2. 当具体类最终扩展/混合这些特征时,某些类/特征必须实现 A

考虑以下示例:

scala> trait User { def name: String }
defined trait User

scala> trait Tweeter {
| user: User =>
| def tweet(msg: String) = println(s"$name: $msg")
| }
defined trait Tweeter

scala> trait Wrong extends Tweeter {
| def noCanDo = name
| }
<console>:9: error: illegal inheritance;
self-type Wrong does not conform to Tweeter's selftype Tweeter with User
trait Wrong extends Tweeter {
^
<console>:10: error: not found: value name
def noCanDo = name
^

如果TweeterUser的子类,则不会出现错误。在上面的代码中,每当使用 Tweeter 时,我们都需要一个 User,但是没有提供 User 错误,所以我们得到了一个错误。现在,上面的代码仍在范围内,请考虑:

scala> trait DummyUser extends User {
| override def name: String = "foo"
| }
defined trait DummyUser

scala> trait Right extends Tweeter with User {
| val canDo = name
| }
defined trait Right

scala> trait RightAgain extends Tweeter with DummyUser {
| val canDo = name
| }
defined trait RightAgain

使用Right,可以满足混入User的要求。然而,上面提到的第二个要求并没有得到满足:对于扩展Right的类/特征来说,实现User的负担仍然存在。

通过RightAgain,这两个要求都得到满足。提供了UserUser 的实现。

有关更多实际用例,请参阅本答案开头的链接!但是,希望现在你明白了。

关于scala - self 类型和特质子类有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1990948/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com