"`class declaration head` { val_name : Type => `class body` }"的语法意义是什么?

8 浏览
0 Comments

"`class declaration head` { val_name : Type => `class body` }"的语法意义是什么?

阅读一些关于Scala的文章时,我发现了一些具有奇怪语法的示例,可能我对其理解有误。

class Child[C <: Child[C]] {
  some_name : C =>                   // 这里,这是什么意思?
   var roomie : Option[C] = None
   def roomWith(aChild : C)= { 
     roomie = Some(aChild)
     aChild.roomie = Some(this) 
   }
}
class Boy extends Child[Boy]

我发现了类似的带特质的示例。

这是否意味着我在类范围内声明this对象的类型为C

0
0 Comments

在JaimeJorge的回答中,除了继承要求外,还可以使用self types来为外部实例命名,如果您想从内部类中引用它:

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

在这个例子中,我们定义了一个名为Company的类,它有一个名为name的参数。在类的声明中,我们使用了self type的语法来为外部实例命名为company。然后,在Company类内部我们定义了一个名为Department的内部类,它也有一个名为name的参数。在Department类的toString方法中,我们使用了company.name来引用外部实例的name属性。

接下来,我们创建了一个名为c的Company实例,并传入参数"ACME"。然后,我们使用这个实例创建了一个名为d的Department实例,传入参数"Marketing"。最后,我们打印了d的toString方法的结果。

输出结果为:Department Marketing of ACME。它显示了Department实例的名字和所属的Company实例的名字。

这个例子中使用了self types来给外部实例命名,这样我们就可以在内部类中引用它。这对于需要在内部类中访问外部实例的属性或方法非常有用。

希望这个例子对您有所帮助!

0
0 Comments

在上面的代码示例中,使用了self types的一个很有用的应用,即CRTP(Curiously Recurring Template Pattern)的一种更简洁的实现方式。CRTP是一种设计模式,通过在类定义中将自身类型作为参数传递给基类,实现了在编译时期进行类型检查和静态多态性的功能。

在上面的代码中,定义了一个抽象类Base,它有一个类型参数Sub,并且要求子类必须是Sub类型。在Base类的实现中,定义了一个add方法,用于将两个Sub类型的对象进行相加并返回结果。然后通过case class Vec3继承Base类,并实现了add方法。

在代码的后面,尝试对继承关系进行欺骗的操作是不起作用的。例如,尝试定义一个类Foo继承Base[Vec3],但是在add方法中返回了一个Vec3类型的参数,这是不符合Base类的要求的。编译器会报错,提示"illegal inheritance; self-type Foo does not conform to Base[Vec3]'s selftype Base[Vec3] with Vec3"。

这个问题的原因是,通过使用self types,我们可以在编译时期对继承关系进行更严格的限制,确保子类符合基类的要求。在这个例子中,Base类要求子类必须是Sub类型,而Foo类并不是Sub类型,因此编译器报错。

解决这个问题的方法是,修改Foo类的定义,使其符合Base类的要求。在这个例子中,可以将Foo类定义为继承Base[Vec3]并实现add方法,确保返回的类型是Sub类型(即Vec3类型)。

总结起来,通过使用self types,我们可以在编译时期对继承关系进行更严格的限制,避免出现不符合基类要求的子类定义。这样可以提高代码的可靠性和可维护性。

0
0 Comments

class declaration head { val_name : Type => class body }的语法含义是self type annotation,即class Child必须是类型C的实例,即为给定类创建必须满足的继承依赖关系。

可以通过以下示例进行说明:

scala> trait Baz
defined trait Baz
scala> class Foo {
     | self:Baz =>
     | }
defined class Foo
scala> val a = new Foo
: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
scala> class Bar extends Foo with Baz
defined class Bar

在这个例子中,类Foo需要同时是Baz类型。满足这个要求后,可以创建Foo实例。同样,在定义一个新类(在这个例子中是Bar)时,它也必须是Baz类型。

更多信息请参见:http://www.scala-lang.org/node/124

0