2015-09-04 30 views
0

是否可以定義一個代表多個數據類型的類型別名?scala類型別名 - 如何有一個代表多種數據類型的類型

package object scala { 
    type SingleDimension = Double 
    type MultiDimensionMap = Map[String, Double] 
    type MultiDimensionList = List[Tuple2[String, Double]] 
} 

例如,我需要一個suptertype讓我們說DataDimension只代表上面三種類型。所以我可以做以下事情:

trait AbstractDataWorker[T] { 

    def formula(d: Double): T 
} 


class multiDimensionWorker extends AbstractDataWorker[MultiDimensionMap] { 

    type T = MultiDimensionMap 
    override def formula(d: Double): MultiDimensionMap = { 

    Map[String, Double]() 
    } 

} 

class singleDimensionWorker extends AbstractDataWorker[SingleDimension] { 

    type T = SingleDimension 
    override def formula(d: Double): SingleDimension = { 
    2.0 
    } 

} 

但是,下面應該給編譯錯誤。目前它的工作。

class stringDimensionWorker extends AbstractDataWorker[String] { 

    type T = String 
    override def formula(d: Double): String = { 

    "hello" 
    } 

} 

回答

5

你可以不是擴展類型別名的單一性狀他們真正的類:

sealed trait DimensionLike 
case class SingleDimension(value: Double) extends DimensionLike 
case class MultiDimensionMap(value: Map[String, Double]) extends DimensionLike 
case class MultiDinmensionList(value: List[(String, Double)]) extends DimensionLike 

abstract class AbstractDataWorker[T <: DimensionLike] { 
    def formula(d: Double): T 
} 

class MultiDimensionWorker extends AbstractDataWorker[MultiDimensionMap] { 
    // ... 
} 

或者你可以用這些類型別名隱含實現一個類型類。然後,讓AbstractDataWorkerabstract class,並添加開往這個類型類上下文其類型參數:

type SingleDimension = Double 
type MultiDimensionMap = Map[String, Double] 
type MultiDimensionList = List[(String, Double)] 

sealed trait IsDimensionLike[T] 
object IsDimensionLike { 
    implicit object singleDimension extends IsDimensionLike[SingleDimension] 
    implicit object multiDimensionMap extends IsDimensionLike[MultiDimensionMap] 
    implicit object multiDimensionList extends IsDimensionLike[MultiDimensionList] 
} 

abstract class AbstractDataWorker[T : IsDimensionLike] { 
    def formula(d: Double): T 
} 

class MultiDimensionWorker extends AbstractDataWorker[MultiDimensionMap] { 
    // ... 
} 
+0

真棒!我想到了第一個解決方案,但是定義了額外的'value'參數,並且返回了case類而不是像map,list或double這樣的簡單類型,這看起來並不吸引人。第二種解決方案是正確的,但我無法理解它:(你能解釋發生了什麼的語義或者指向一些參考文檔嗎?我被許多東西拋出:「隱式對象singleDimension」是一個伴隨對象什麼是T:IsDimensionLike?當我從SingleDimensionWorker返回Double(2.0)後面發生了什麼? – nir

+0

@nir Google「scala typeclass pattern」。基本上'AbstractDataWorker [T:IsDimensionLike]'是語法(抽象數據工作者[T])(隱含的ev:IsDimensionLike [T])'(這就是爲什麼你需要'抽象類',特徵不能帶參數)爲了創建某種類型的'AbstractDataWorker',編譯器必須能夠找到這個類型的隱式值IsDimensionLike,它搜索的一個地方是它所需要的類型的伴隨對象(IsDimensionLike),並且它只包含你允許的類型的含義。被「密封」禁止在別處使用其他類型。 – Kolmar