“类声明头” { val_name : Type => 的语法含义是什么? `类体`}”

发布于 2024-12-14 04:09:22 字数 432 浏览 1 评论 0原文

在阅读一些有关 Scala 的文章时,我发现了一些语法奇怪的示例,我可能会理解错误

class Child[C <: Child[C]] {
  some_name : C =>                   // here, what does it mean?
   var roomie : Option[C] = None

   def roomWith(aChild : C)= { 
     roomie = Some(aChild)
     aChild.roomie = Some(this) 
   }
}
class Boy extends Child[Boy]

我发现了类似的具有特征的例子。

这是否意味着我在类作用域中将 this 对象声明为 C 类型?

When reading some articles about Scala, I found some examples with a curious syntax, which I might understand incorrectly

class Child[C <: Child[C]] {
  some_name : C =>                   // here, what does it mean?
   var roomie : Option[C] = None

   def roomWith(aChild : C)= { 
     roomie = Some(aChild)
     aChild.roomie = Some(this) 
   }
}
class Boy extends Child[Boy]

I found similar examples with traits.

Does it mean that I declare this object in a class scope to by type of C ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雨巷深深 2024-12-21 04:09:22

它是一个自我类型注释。

这意味着类Child 必须是C 类型,即创建必须满足给定类的继承依赖关系。

一个小例子:

scala> trait Baz
defined trait Baz


scala> class Foo {
     | self:Baz => 
     | }
defined class Foo


scala> val a = new Foo
<console>:9: error: class Foo cannot be instantiated because it does not conform to its self-type Foo with Baz
       val a = new Foo
               ^

scala> val a = new Foo with Baz
a: Foo with Baz = $anon$1@199de181


scala> class Bar extends Foo with Baz
defined class Bar

在这种情况下,Foo 也需要是 Baz
满足该要求后,可以创建一个 Foo 实例。
此外,定义一个新类(在本例中为 Bar)还要求它也是 Baz

看:
http://www.scala-lang.org/node/124

It is a self type annotation.

This means that class Child must be of type C, i.e., creates inheritance dependencies which must satisfied for a given class.

A small example:

scala> trait Baz
defined trait Baz


scala> class Foo {
     | self:Baz => 
     | }
defined class Foo


scala> val a = new Foo
<console>:9: error: class Foo cannot be instantiated because it does not conform to its self-type Foo with Baz
       val a = new Foo
               ^

scala> val a = new Foo with Baz
a: Foo with Baz = $anon$1@199de181


scala> class Bar extends Foo with Baz
defined class Bar

In this case Foo is required to also be a Baz.
Satisfying that requirement, a Foo instance can be created.
Also, defining a new class (in this case Bar) there is also the requirement of it being Baz as well.

See:
http://www.scala-lang.org/node/124

空‖城人不在 2024-12-21 04:09:22

self 类型的一个非常有用的应用是 CRTP 的不太详细的实现( http://en.wikipedia.org /wiki/Curiously_recurring_template_pattern ),例如

abstract class Base[Sub] {
  self:Sub =>
  def add(s:Sub) : Sub
}

case class Vec3(x:Double,y:Double,z:Double) extends Base[Vec3] {
  def add(that:Vec3) = Vec3(this.x+that.x, this.y+that.y, this.z+that.z)
}

尝试用继承“欺骗”是行不通的:

class Foo extends Base[Vec3] {
  add(v:Vec3) = v
}

//error: illegal inheritance;
//self-type Foo does not conform to Base[Vec3]'s selftype Base[Vec3] with Vec3
//      class Foo extends Base[Vec3] {

One very useful application of self types is a less verbose implementation of the CRTP ( http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern ), e.g.

abstract class Base[Sub] {
  self:Sub =>
  def add(s:Sub) : Sub
}

case class Vec3(x:Double,y:Double,z:Double) extends Base[Vec3] {
  def add(that:Vec3) = Vec3(this.x+that.x, this.y+that.y, this.z+that.z)
}

Attempts to "cheat" with the inheritance won't work:

class Foo extends Base[Vec3] {
  add(v:Vec3) = v
}

//error: illegal inheritance;
//self-type Foo does not conform to Base[Vec3]'s selftype Base[Vec3] with Vec3
//      class Foo extends Base[Vec3] {
你是暖光i 2024-12-21 04:09:22

除了 JaimeJorge 响应中的继承要求之外,如果您想从内部类引用外部实例,还可以使用 self 类型为外部实例命名:

scala> class Company(name: String) {
     |   company =>
     |   class Department(name: String) {
     |     override def toString = "Department "+ name +" of "+ company.name
     |   }
     | }
defined class Company

scala> val c = new Company("ACME")
c: Company = Company@56a57bb2

scala> val d = new c.Department("Marketing")
d: c.Department = Department Marketing of ACME

In addition to the inheritance requirement in JaimeJorge's response, self types can be used to give the outer instance a name if you want to refer to it from an inner class:

scala> class Company(name: String) {
     |   company =>
     |   class Department(name: String) {
     |     override def toString = "Department "+ name +" of "+ company.name
     |   }
     | }
defined class Company

scala> val c = new Company("ACME")
c: Company = Company@56a57bb2

scala> val d = new c.Department("Marketing")
d: c.Department = Department Marketing of ACME
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文