2014-09-05 20 views
1

結合明確指定上下文爲什麼這是允許的:Scala中:在第二個構造

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

雖然這不是:

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

編譯消息:

的Foo [O]不參數

有沒有什麼辦法可以在構造函數中顯式提供上下文綁定?

回答

2

好書說,綁定的上下文是equivalent to the implicit evidence.

正如@加布裏埃萊 - 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時,也無法做任何事情。 (See here

解決方法的原因是None <:< Option[Nothing] <:< Option[O]適用於任何類型的參數。

正如@加布裏埃萊 - petronella還指出,在同伴你可以做任何:

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

按理說,編譯器可以等來決定你的意思是調用,然後一個隱含是否需要該構造函數,在這種情況下,忽略隱含在你的輔助控制器中。但構造函數在Scala中特意簡單。

+0

我明白附加的arg部分,這就是我在自定義構造函數中指定的(無)。 爲什麼我不能像我想要做的那樣稱呼它仍然是我的一個謎。 – eprst 2014-09-07 07:05:54

+0

查看上面的-Xprint:parser的輸出。你的兩個arg調用變成了三個。我應該說它會把你的ctor和arg附加到你的ctor調用中。 – 2014-09-07 11:03:24