scala类型别名-如何拥有表示多个数据类型的类型

scala类型别名-如何拥有表示多个数据类型的类型,scala,Scala,是否可以定义表示多个数据类型的类型别名 package object scala { type SingleDimension = Double type MultiDimensionMap = Map[String, Double] type MultiDimensionList = List[Tuple2[String, Double]] } e、 我需要一个suptertype,比如说DataDimension,它只表示以上三种类型。因此,我可以做到以下几点: trait A

是否可以定义表示多个数据类型的类型别名

package object scala {
  type SingleDimension = Double
  type MultiDimensionMap = Map[String, Double]
  type MultiDimensionList = List[Tuple2[String, Double]]
}
e、 我需要一个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"
  }

}

您可以使它们成为扩展单个特征而不是类型别名的真实类:

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] {
  // ...
}

您可以使它们成为扩展单个特征而不是类型别名的真实类:

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] {
  // ...
}

令人惊叹的!我想到了第一种解决方案,但定义额外的“value”参数并返回case类而不是map、list或double这样的简单类型看起来并不吸引人。第二个解决方案是正确的,但我无法理解:(你能解释那里发生的事情的语义吗,或者给我指一些参考文档。我被那里的很多东西甩了:“隐式对象singleDimension”是某种内部singleDimension类的伴生对象吗?;当我返回Double(2.0)时,t:IsDimensionLike是什么从我的SingleDimensionWorker看,幕后发生了什么?@nir Google“scala typeclass模式”。基本上,
AbstractDataWorker[T:IsDimensionLike]
AbstractDataWorker[T](隐式ev:IsDimensionLike[T])
的语法糖(这就是为什么需要
抽象类,traits不能接受参数)。要生成某种类型的
AbstractDataWorker
,编译器必须能够找到该类型的隐式值
IsDimensionLike
。它搜索的位置之一是它所需类型的伴生对象(
IsDimensionLike
)。其中只有允许的类型的隐式。
IsDimensionLike
sealed
以禁止在其他地方允许其他类型。太棒了!我想到了第一种解决方案,但定义了额外的“value”参数并返回case类,而不是简单的类型,如map、list或double,看起来不太吸引人。第二种解决方案是rig(你能解释一下那里发生的事情的语义吗,或者给我指一些参考文档。我被那里的很多东西吓坏了:“隐式对象singleDimension”是某种内部singleDimension类的伴生对象吗?;当我返回Double(2.0)时,t:IsDimensionLike是什么从我的SingleDimensionWorker看,幕后发生了什么?@nir Google“scala typeclass模式”。基本上,
AbstractDataWorker[T:IsDimensionLike]
AbstractDataWorker[T](隐式ev:IsDimensionLike[T])
的语法糖(这就是为什么需要
抽象类,traits不能接受参数)。要生成某种类型的
AbstractDataWorker
,编译器必须能够找到该类型的隐式值
IsDimensionLike
。它搜索的位置之一是它所需类型的伴生对象(
IsDimensionLike
)。其中只有允许的类型的隐式。
IsDimensionLike
sealed
以禁止在其他地方允许其他类型。