18

defと に適用すると、Scala の型推論に違いが見られましたval

を使用して、 type の値を返すdef抽象 nullary メソッドを定義できます。関数リテラルを使用して実装する場合、パラメーターの型を指定する必要はありません。コンパイラーによって推論できるためです。constInt => Intconst

trait D {
  def const: Int => Int
}
object D extends D {
  def const = i => i + 1
}

これで問題ありません。(欠点として、へのアクセスごとに新しい関数インスタンスが作成されますD.const。)

を使用して類似の構造を考えてみましょうval

trait V {
  val const: Int => Int
}
object V extends V {
  val const = i => i + 1
}

これはコンパイルされず、失敗します

error: missing parameter type
   val const = i => i + 1
               ^

なんで?

4

2 に答える 2

2

オプション -Xprint all を使用してこのコードをビルドすると、次のことがわかります。

abstract trait V extends scala.AnyRef {   
<stable> <accessor> def const: Int => Int
};

final object V extends java.lang.Object with V with ScalaObject {

def this(): object V = {
  V.super.this();
  ()
};

private[this] val const: <error> => <error> = ((i: <error>) => i.+(1));
<stable> <accessor> def const: <error> => <error> = V.this.const
}

そのため、プライベート val とアクセサの作成時にエラーが発生します。th コンパイラは、アクセサ def const を作成する前に、val const に影響する値を評価しようとします。

trait で定義された val const を見ると、プライベート val の作成が無効になっていることがわかります。これは、def const アクセサーの定義にすぎないためです。

以前の定義 (特性またはスーパークラス内) の推論型は、値を評価するためではなく、アクセサーを作成しようとしたときにのみ発生したと思います。

そして、最後の def const については、型は private[this] val const type : error => error のみに基づいています

于 2012-05-24T22:07:04.673 に答える
1

Scala 2.9.1 の時点で、これは「仕様どおり」です。SI-2742からの Martin Odersky の引用:

メソッドの場合、継承された抽象メソッドの戻り値の型は、右側の期待される型として取得されます。値については、そのような規則はありません。だから、これは私が見ているように、仕様の拡張要求になります。

このチケットは優先度が低く、2009 年後半に最初に議論されて以来変更されていないため、すぐに変更される可能性は低いと思われます。

于 2012-06-05T10:42:34.667 に答える