scala中是否存在表示当前类型的"SELF"类型?

Dam*_*ian 13 inheritance scala

我正在学习Scala,有一件事我无法找到该语言:

前段时间我在Lisaac编程非常舒服,在Lisaac中,我可以编写一个PERSON带有插槽的类list:ARRAY[SELF],这相当于有list:ARRAY[PERSON],因为SELF是该插槽的对象类型.

但是,通过使用SELF,如果我写的第二类STUDENT,从继承PERSON,然后STUDENT将继承该槽改变SELFSTUDENT,所以STUDENT就会有一个列表STUDENT,而不是PERSON.

可以在Scala中完成吗?我无法找到任何相关信息.

谢谢!

Bla*_*ade 15

这有一个习惯用法,它在集合框架中广泛使用(在所有*Like类中,例如TraversableLike).您需要将self-type添加为超类的类型参数(如C++中可能与CRTP一样):

trait Person[+Self] {
  this: Self => //Declare that any concrete subclass must implement Self; therefore, this can be used with type Self.
  //val list: Array[Self] //Not sure that this will work so easily, for the same reason new T[] does not work in Java.
  val list = Seq[Self]() //No problem here; Array is really special.
}
Run Code Online (Sandbox Code Playgroud)

在定义了这个类之后,我们可以尝试在解释器中定义子类:

scala> class Student extends Person[Student]
defined class Student
scala> (new Student).list
res0: Seq[Student] = List() //Note the result type
scala> class Student2 extends Person[Student] //Note the mistake
<console>:9: error: illegal inheritance;
 self-type Student2 does not conform to Person[Student]'s selftype Person[Student] with Student
       class Student2 extends Person[Student]
Run Code Online (Sandbox Code Playgroud)

一个没有阻止的错误就是有了这个定义,其中Self没有被重新定义:

scala> class SpecStudent extends Student
defined class SpecStudent
Run Code Online (Sandbox Code Playgroud)

感谢+前面的Self,这使得它成为一个协变类型参数(我不解释它是什么),但这至少是可能的:

scala> class SpecStudentCorrect extends Student with Person[SpecStudentCorrect]

scala> (new SpecStudentCorrect).list
(new SpecStudentCorrect).list
res1: Seq[SpecStudentCorrect] = List()
Run Code Online (Sandbox Code Playgroud)

  • 如果您阅读对该答案的评论,您会同意我的观点。 (2认同)

Lac*_*lan 8

我不确定这对你是否真的有用,但我能想到的最接近的是this.type.例如:

scala> class A { val l: List[this.type] = Nil }  
defined class A

scala> new A().l
res3: List[A] = List()

scala> class B extends A
defined class B

scala> new B().l
res4: List[B] = List()
Run Code Online (Sandbox Code Playgroud)

  • 我不认为"this.type"是这里所要求的."this.type"是单例类型; 它只是"this"实例的类型.尽可能尝试,有效元素"List [this.type]"可以包含"this". (9认同)