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);
        ()
      }
    }

所以错误是由于附加的参数。

您也不能在辅助构造函数中执行任何操作来强制类型参数,即将其实例化为特定类型 arg。(见这里。)

解决方法有效的原因是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 回答