`this.type`:为什么不编译?

时间:2017-08-24 19:03:13

标签: scala types

class Foo { 
   def copy: this.type = new Foo().asInstanceOf[this.type]
   def multiply(n: Int): Seq[this.type] = (0 until n).map(_ => copy)
}

此代码无法编译,错误如下:

<console>:33: error: type mismatch;
 found   : scala.collection.immutable.IndexedSeq[Foo]
 required: Seq[Foo.this.type]

我无法想到对此的解释:copy返回this.typemultiply只是调用.copy ...为什么结果不兼容?

这是一个编译器错误,还是有一个实际的原因我错过了为什么这不起作用?

2 个答案:

答案 0 :(得分:0)

它是一个bug或JVM限制。要使其有效,请在this.type中为Foo创建类型别名,或明确指定map的类型参数。

但是,我不认为有一个用例需要运行时转换为this.type。无论你有什么用例,都应该有另一种更好的方法。

答案 1 :(得分:0)

只是类型推断不会推断单身人士。这不是一个错误,而是一个有意识的语言设计决策。您需要为map

提供明确的参数
(0 to n).map[this.type, Seq[this.type]] { _ => copy }

如果您愿意,可以使用绑定的Singleton类型来创建推断单例类型的方法:

def replaceAll[In, Elem <: Singleton, Out](coll: FilterMonadic[_, In])(e: Elem)(implicit cbf: CanBuildFrom[In, Elem, Out]): Out
= coll.map { _ => e }

用法:

replaceAll(0 to n)(x: x.type) // Won't work without ascription, but cleaner than above

另外,请不要使用asInstanceOf[this.type]。单例类型基于引用相等,而不是equals。因此,你会得到这样的东西:

val foo = new Foo
val foo2: foo.type = foo.copy
foo2.isInstanceOf[foo.type] // false because foo2 neq foo

您可能需要F-bounds