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

このコードのようなエラーでコンパイルに失敗します。私はこれについての説明を考えることはできません`this.type`:なぜこれはコンパイルされませんか?

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

:結果がでない理由copy戻りthis.typemultiplyはちょうど... .copyを呼び出します互換性がある?

これはコンパイラのバグですか、実際にはこれが機能しない理由が分かりません。

答えて

0

バグかJVMの制限です。それを動作させるには、this.typeの型エイリアスをFooに作成するか、mapの型パラメータを明示的に指定します。

しかし、私はthis.typeにランタイムキャストを必要とするユースケースがあるとは思わない。あなたが持っているユースケースが何であれ、それに代わるより優れたアプローチが必要です。

+0

キャストは本当に悪い考えのように思えます。また、コンパイラは、制約のないシングルトンタイプを推測することを好まない。 'Identity(foo)'は 'foo.type'ではなく' foo'です。たとえば、 'object foo'以外のものです。 –

+1

実際に 'identity(foo):foo.type'ではなく' identity(List(foo).map(_ => foo)):List [foo.type] 'なので、' CanBuildFrom'の推論のためです。 –

0

単なる推論では、シングルトンは推論されません。これはバグではなく、意識的な言語設計の決定です。あなたはmapに明示的なパラメータを与える必要があります。

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

使用法:

あなたがそう望むならば
(0 to n).map[this.type, Seq[this.type]] { _ => copy } 

は、あなたがシングルトンの種類を推測する方法を作成するためにバインドされSingletonタイプを使用することができます

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をしたいことがあります。

+0

しかし、他の答えに私のコメントを参照してください。 –

+0

待ってください...あなたは 'def copy:this.type = clone()。asInstanceOf [this.type]'のようなものは動作しないはずはありませんか?それは私のために働いているので... – Dima

+0

私は 'isInstanceOf'が動作を停止することを意味しました。 'asInstanceOf'はうまく動作しますが、isInstanceOf'がどのように破られているかによって、そのように使用すべきではありません。 – HTNW

関連する問題