2016-01-03 91 views
0

請考慮以下關於類的定義。scala:具有類型標記的類的空構造函數

case class DiscreteProperty[T <: AnyRef](
    name: String, 
    sensor: T => String, 
    range: Option[List[String]] 
)(implicit val tag: ClassTag[T]) extends TypedProperty[T, String] { 

    /// some stuff here 
} 

我收到以下錯誤在一些點:

Can't instantiate 'edu.illinois.cs.cogcomp.saul.datamodel.property.features.discrete.DiscreteProperty$$anon$2': 

我想這是因爲該類沒有一個空的構造。我怎樣才能爲這個類定義一個空構造函數?我嘗試以下,但它給我以下錯誤:

def this() { 
    this("funnyName", T => "" ,Option(List())) 
    } 

,沒有這些工作:

def this[T]() { 
    this("funnyName", T => "" ,Option(List())) 
    } 

def this[T]() { 
    this[T]("funnyName", T => "" ,Option(List())) 
    } 

任何想法如何創建一個空的構造這個類與標籤?

回答

3

問題是,您沒有在任何空的構造函數中包含隱式參數。您將主構造函數視爲具有簽名(String, T => String, Option[List[String]]),但這並不完全正確。實際上,它是(String, T => String, Option[List[String]])(ClassTag[T])(注意參數ClassTag)。

通常這不會是一個問題,因爲隱式參數將從該構造函數的範圍中檢索。然而,ClassTag有點特別 - 它在編譯時填入ClassTag對應於你的任何T。每個輔助構造函數中的問題是T仍然是通用的,因此編譯器不知道要包含哪個ClassTag:在該範圍內沒有可用的隱式參數。

那麼,你如何解決它?最簡單的方法可能是包括任何輔助構造的隱含參數:

def this()(implicit tag: ClassTag[T]) = this("funnyName", T => "", Option(List())) 

需要注意的是,你並不需要明確地證明了ClassTag到鏈構造;它現在成爲範圍的一部分,並將被隱式使用。當然,你可以決定這樣做:

def this()(implicit tag: ClassTag[T]) = this("funnyName", T => "", Option(List()))(tag) 
相關問題