2011-11-07 43 views
7

Al leer algunos artículos sobre Scala, encontré algunos ejemplos con una curiosa sintaxis, que podría comprender incorrectamente ¿Cuál es el significado de sintaxis de "` class declaration head` {val_name: Type => `class body`}"

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] 

Encontré ejemplos similares con los rasgos.

¿Significa que declaro el objeto this en un alcance de clase por tipo de C?

+2

Aquí es [respuesta de Martin Odersky] (http://stackoverflow.com/questions/4017357/difference-between-this -y-self-in-self-type-annotations/4018995 # 4018995) a esta pregunta. –

Respuesta

10

Es una anotación de tipo propio.

Esto significa que la clase Child debe ser del tipo C, es decir, crea dependencias de herencia que deben cumplirse para una clase determinada.

Un pequeño ejemplo:

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 = [email protected] 


scala> class Bar extends Foo with Baz 
defined class Bar 

En este caso Foo está obligado a ser también un Baz. Satisfaciendo ese requisito, se puede crear una instancia Foo. Además, definir una nueva clase (en este caso Bar) también existe el requisito de que sea Baz también.

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

2

Además del requisito de la herencia en la respuesta de JaimeJorge, tipos de auto pueden ser utilizados para dar la instancia externa un nombre si desea hacer referencia a ella desde una clase interna:

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 = [email protected] 

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

Una aplicación muy útil de auto tipos es una implementación menos detallada de la CRTP (http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), por ejemplo

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) 
} 

Los intentos de "engañar" con la herencia no funcionarán:

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] { 
Cuestiones relacionadas