2011-11-07 49 views
7

在阅读一些关于Scala的文章时,我发现了一些好奇的语法示例,我可能会错误地理解它 “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] 

我发现了与特征相似的例子。

是否意味着我宣布this对象在类范围内按类型C

+2

这里的[马丁·奥德斯基的答案](http://stackoverflow.com/questions/4017357/difference-between-this - 自我在自我类型注释/ 4018995#4018995)到这个问题。 –

回答

10

这是一个自我标注。

这意味着类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 = [email protected] 


scala> class Bar extends Foo with Baz 
defined class Bar 

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

参见: http://www.scala-lang.org/node/124

2

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

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

自我类型的一个非常有用的应用是不太详细的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] { 
相关问题