3

次のコード スニペット (scala 2.10.3 を使用)では、 TestClass1はエラー「value toInt is not a member of String」でコンパイルされませんが、 TestClass2は正常にコンパイルされます。

trait TestTrait {
  implicit def test: (String => Int)
}

object TestClass1 extends TestTrait {
  implicit val test = (value: String) => value.toInt
}

object TestClass2 extends TestTrait {
  implicit def test = (value: String) => value.toInt
}

toInt関数を提供するaugmentString()によるStringOpsの暗黙的な変換は、 TestClass1 では適用されませんが、 TestClass2では適切に適用されます。なぜこれが当てはまるのか、またtestをdefの代わりにval保つ方法を教えてもらえますか?

4

1 に答える 1

2

This is a limitation of implicit definitions when the return type needs to inferred, I think. You are in a somewhat similar situation as defining a recursive method. That is to say, the "open" implicit definition triggers implicit lookup in its body, which in theory could be recursive. (At least that's my explanation of this limitation).

You can either annotate the type:

object TestClass1 extends TestTrait {
  implicit val test: String => Int = value => value.toInt  // or _.toInt
}

or remove the implicit keyword—since it is implementing the implicit method from TestTrait, you do not need to re-state the implicit keyword:

object TestClass1 extends TestTrait {
  val test = (value: String) => value.toInt
}
于 2013-10-14T12:19:39.047 に答える