1

これが許可される理由:

class Foo[O: Option](s: String)
new Foo[Any]("foo")(None)

これはそうではありませんが:

class Foo[O: Option](s: String) {
    def this() = this("foo")(None)
}

コンパイラ メッセージ:

Foo[O] はパラメータを取らない

コンストラクターで明示的にバインドされたコンテキストを提供する方法はありますか?

4

1 に答える 1

2

グッドブックは、文脈の束縛は暗黙の証拠と同等であると述べています。

@gabriele-petronellaが指摘したように:

class Foo[O](s: String)(implicit o: Option[O]) {
  def this() = this("foo")(None)
}

しかし、コンテキストがバインドされている場合、パーサーは自動的に証拠パラメーターを追加します。

    class Foo[O] extends scala.AnyRef {
      <paramaccessor> private[this] val s: String = _;
      implicit <synthetic> <paramaccessor> private[this] val evidence$1: Option[O] = _;
      def <init>(s: String)(implicit evidence$1: Option[O]) = {
        super.<init>();
        ()
      };
      def <init>()(implicit evidence$2: Option[O]) = {
        <init>("foo")(None)(evidence$2);
        ()
      }
    }

したがって、エラーは追加された引数が原因です。

また、2 次コンストラクターで型パラメーターを強制すること、つまり、特定の型引数にインスタンス化することはできません。(こちらをご覧ください。)

回避策が機能する理由は、None <:< Option[Nothing] <:< Option[O]すべての型パラメーターに対してです。

@gabriele-petronella も指摘しているように、コンパニオンでは何でもできます。

object Foo { def apply() = new Foo[Int]("five")(Some(5)) }

おそらく、コンパイラは、呼び出すコンストラクターを決定するのを待ってから、暗黙的なものが必要かどうかを判断し、その場合、セカンダリ ctor への暗黙的なものを無視することができます。しかし、コンストラクターは Scala では意図的に単純化されています。

于 2014-09-06T00:49:10.107 に答える