问题描述
考虑以下示例:
trait Supe {
type Out <: Supe
def out: Out
}
class Reif1 extends Supe {
type Out = Reif1
override def out: Out = this
}
class Reif2 extends Supe {
type Out >: this.type <: Reif2
override def out: Out = this
}
class Reif1
显然应该可以工作。 type Out
被改写并成为类型别名
class Reif2
也可以,但是认真吗? type Out
仅定义了上限/下限,并且边界还不够严格:this.type
是单例类型,而Reif2
是类类型。因此,如果实例化Out
,Reif2
将会是什么样?是this.type
吗?还是Reif2
?但是更大的问题应该是:为什么scalac 2.12 / 2.13允许对其进行编译?
解决方法
在Scala(或DOT演算sorted()
1)中,所有类型都是区间。
type Out = Reif1
是(或应该是)type Out >: Reif1 <: Reif1
。
不受限制的抽象类型type Out
是type Out >: Nothing <: Any
。
如果
Out
实例化,Reif2
到底会是什么样?
它将完全保持type Out >: this.type <: Reif2
val r = new Reif2
import scala.reflect.runtime.universe._
typeOf[r.Out] // App.r.Out
showRaw(typeOf[r.Out]) // TypeRef(SingleType(ThisType(App),TermName("r")),TypeName("Out"),List())
typeOf[r.Out].typeSymbol.isAbstract // true
typeOf[r.Out].typeSymbol.typeSignature // >: Reif2.this.type <: App.Reif2
如果将type Out >: this.type <: Reif2
中的Reif2
替换为type Out = this.type
(或type Out = Reif2
或type Out = Supe
),则isAbstract
将返回false
2(请参见抽象类型的应用)
Abstract type member of a singleton object(请参阅为什么不容易检查type T >: L <: U
不是抽象的东西)
What is the meaning of a type declaration without definition in an object?
Concrete classes can have abstract type members #1753
SI-8217 allow abstract type members in objects #4024
Abstract type members are incorrectly forbidden in objects (unless inherited) #8217