Что такое синтаксическое значение "главы объявления класса" {val_name: Type => `body body`}" - PullRequest
7 голосов
/ 07 ноября 2011

Читая некоторые статьи о 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?

Ответы [ 3 ]

10 голосов
/ 07 ноября 2011

Это аннотация самостоятельного типа.

Это означает, что класс 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 / узел / 124

3 голосов
/ 07 ноября 2011

Одним из очень полезных приложений типов 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] {
2 голосов
/ 07 ноября 2011

В дополнение к требованию наследования в ответе JaimeJorge можно использовать собственные типы, чтобы дать внешнему экземпляру имя, если вы хотите сослаться на него из внутреннего класса:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...