Scala:是否可以将类型参数强制为两种类型之一?

时间:2015-04-06 14:56:12

标签: scala

在以下语句中,类型参数A必须是AnotherClass的子类:

trait MyClass[A <: AnotherClass] { ... }

如果类型参数A必须是某种类型或其他类型,该怎么办?例如,我需要指定一个必须是StringOption[String]的类型参数。

我不知道这是否真的可行......也许还有一些其他技术可以解决这个问题。

2 个答案:

答案 0 :(得分:2)

根据您的评论,这对您有何帮助?

sealed trait Entity[T] { def id: T; def id_=(v: T): Unit }
trait UnmodifiableEntity extends Entity[String]
trait ModifiableEntity extends Entity[Option[String]]

答案 1 :(得分:0)

你可以使用Either和隐式转换来获得接近你想要的东西(在我看来)

trait Entity[T] {
  def id: Either[T, Option[T]]
  def id_=(v: Either[T, Option[T]]): Unit
}

object Entity {
  implicit def toLeftEither[T](t: T): Either[T, Option[T]] = Left(t)
  implicit def toRightEither[T](t: Option[T]): Either[T, Option[T]] = Right(t)

  implicit def fromLeftEither[T](e: Either[T, Option[T]]): T = e.left.get
  implicit def frommRightEither[T](e: Either[T, Option[T]]): Option[T] = e.right.get
}

现在用法:

import Entity._

class E[T] extends Entity[T] {
  private[this] var _id: Either[T, Option[T]] = Right(Option.empty[T])
  def id =  _id
  def id_=(v: Either[T, Option[T]]): Unit = {_id = v}
}

val e = new E[String]
e.id = "1"

val a = e.id // a is of type Either[String, Option[String]]
val b: String = e.id
e.id = Some("1")
val c: Option[String] = e.id

e.id match {
  case Left(id) =>
  case Right(Some(id)) =>
  case _ =>
}

但你必须小心不要混合类型,即

e.id = "1"
val c: Option[String] = e.id

将抛出java.util.NoSuchElementException: Either.left.value on Right