14

this.type を使用して、不変のケース クラスの新しいインスタンスを作成するメソッドを定義できるようにしたいと考えています。このようなもの:

trait Expression
{
  def left : Expression
  def right : Expression

  def new_with_changes(l : Expression, r : Expression) : this.type
}

case class Derived(left : Expression, right : Expression)
{
  def new_with_changes(l : Expression, r : Expression) : this.type =
  {
    new Derived(left, right)
  }
}

残念ながら、コンパイラは文句を言います

test.scala:13: error: type mismatch;
 found   : Derived
 required: Derived.this.type
    new Derived(left, right)
    ^
one error found

新しいケース クラスが this.type と一致しないのはなぜですか?

this.type を Base.new_with_changes で Base に変更し、Derived.new_with_changes で Derived に変更すると動作しますが、this.type の優れた点を見逃しているようです。

編集:質問の本当の意図は、ダウンの呼び出し元がダウンキャストを実行することを宣言する同等の方法をScalaに持たない理由です。これは、this.typeとほぼ同じ方法ですが、一般的なタイプの場合です。簡単にはいかないと思いますが、いいと思います。

4

2 に答える 2

9

this.type は、この特定のインスタンスの一意のタイプです。これはシングルトン型です。同じクラスの他のインスタンスとは異なる型です。これは機能します

class Foo { def f : this.type = this}

しかし、これはそうではありません

class Foo { def f : this.type = new Foo}

this.type はそれほど頻繁には必要ありませんが、他の方法では表現できないいくつかの制約を表現するために使用できます

たとえば、ここで Inner クラスは、各インスタンスの外部メソッドが、それが由来する特定の Outer インスタンスを返すことを示しています。

scala> class Outer{ class Inner { def outer : Outer.this.type = Outer.this}; def f(x : Inner) = println("ok")}
defined class Outer

scala> val o1 = new Outer
o1: Outer = Outer@13c1b69

scala> val o2 = new Outer
o2: Outer = Outer@1a3f178


scala> val in1 = new o1.Inner
in1: o1.Inner = Outer$Inner@627b5c

scala> val in2 = new o2.Inner
in2: o2.Inner = Outer$Inner@158c3b7

scala> val o3 = in1.outer
o3: o1.type = Outer@13c1b69

scala> o1.f(new o3.Inner)  
ok

scala> o1.f(new o2.Inner)
<console>:8: error: type mismatch;
 found   : o2.Inner
 required: o1.Inner
       o1.f(new o2.Inner)

この記事には、this.type を使用してサブクラスの境界を越えたメソッド チェーンを有効にするもう 1 つの良い例があります

scala>   class A { def method1: this.type = this }
defined class A

scala>   class B extends A { def method2: this.type = this }
defined class B

scala> val b = new B
b: B = B@15cb235

scala> b.method1.method2
res3: b.type = B@15cb235
于 2009-04-22T02:19:36.043 に答える