【问题标题】:Convert redundant trait ADT to abstract class with generic value?将冗余特征 ADT 转换为具有通用值的抽象类?
【发布时间】:2022-01-19 13:12:46
【问题描述】:

我的代码为我正在使用的字段包装了一些预期类型。我想转换为抽象类。

  sealed trait SJValue
  case class SJDouble(value: Double) extends SJValue {
    def toValue: Double = value
  }
  case class SJInt(value: Int) extends SJValue {
    def toValue: Int = value
  }
  case class SJString(value: String) extends SJValue {
    def toValue: Double = value
  }
  case class SJBoolean(value: Boolean) extends SJValue {
    def toValue: Boolean = value
  }

我觉得我可以做这样的事情来摆脱重复的 toValue 类,但我不太清楚如何:

abstract class SJValue[T <: ???](value: T) { toValue : T } 如您所见,我将其视为 Int、String、Double 和 Boolean 的 or 类型,所以我不确定实际的类型约束是什么,因为 Any 太宽泛了。

【问题讨论】:

  • 如果将 T 设为密封,为什么还需要类型约束?

标签: scala


【解决方案1】:

你的意思是这样的

sealed trait SJValue[A] {
  def toValue: A
}
case class SJDouble(
  override val toValue: Double
) extends SJValue[Double]
case class SJInt(
  override val toValue: Int
) extends SJValue[Int]
case class SJString(
  override val toValue: String
) extends SJValue[String]
case class SJBoolean(
  override val toValue: Boolean
) extends SJValue[Boolean]

这个?

由于SJValuesealed,它不能是除了这些硬编码 4 之一之外的任何类型。

// [A] can only be Double | Int | String | Boolean
// because you cannot create SJValue with a different A
def extract[A](sjvalue: SJValue[A]) = sjvalue.toValue
sjvalue match {
  case JSDouble(value)  => // Scala knows value is Double
  case JSInt(value)     => // Scala knows value is Int
  case JSString(value)  => // Scala knows value is String
  case JSBoolean(value) => // Scala knows value is Boolean
}

如果您想使用abstract class 而不是trait,它仍然可以是sealed

sealed abstract class SJValue[A](
  val toValue: A
)
case class SJDouble(
  toDouble: Double
) extends JSValue[Double](toValue)
...

如果您想完全摆脱重复,我认为您必须使用 Scala 3,它应该允许您编写:

case class JSValue[A <: Int | Double | String | Boolean](
  toValue: A
)

但这可能有其自身的问题。要在 Scala 2 中达到同样的效果,您必须根据隐含的证据 try some fragile black magic

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-10-22
    • 1970-01-01
    • 2021-05-08
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    相关资源
    最近更新 更多