Scala:在第二个构造函数中显式指定上下文绑定

时间:2014-09-05 22:56:04

标签: scala constructor implicit context-bound

为什么允许这样做:

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

虽然不是这样:

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

编译器消息:

  

Foo [O]不接受参数

有没有办法在构造函数中显式提供上下文绑定?

1 个答案:

答案 0 :(得分:2)

好书说上下文是equivalent to the implicit evidence.

正如@ 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。

引起的

你也不能在辅助构造函数中做任何强制类型参数的事情,也就是说,将它实例化为特定类型的arg。 (See here。)

解决方法的工作原理是None <:< Option[Nothing] <:< Option[O]适用于任何类型的参数。

正如@ gabriele-petronella所说,在同伴中你可以做任何事情:

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

可以说,编译器可以等待决定你要调用哪个构造函数,然后再确定是否需要隐式构造函数,并在这种情况下忽略对辅助ctor的隐式构造函数。但是Scala中的构造函数很简单。