6

我需要返回值,当有人要求一个值时,告诉他们以下三件事之一:

  1. 这是价值
  2. 没有价值
  3. 我们没有关于这个值的信息(未知)

案例 2 与案例 3 略有不同。示例:

val radio = car.radioType
  1. 我们知道值:返回无线电类型,比如“先锋”
  2. 湾。没有价值:返回无
  3. C。我们缺少这辆车的数据,我们不知道它是否有收音机

我想我可能会扩展 scala 的 None 并创建一个 Unknown,但这似乎不可能。

建议?

谢谢!

更新:

理想情况下,我希望能够编写这样的代码:

car.radioType match { 
   case Unknown => 
   case None => 
   case Some(radioType : RadioType) => 
}
4

6 回答 6

13

这是一个准系统实现。您可能想查看 Option 类的源代码,了解一些花里胡哨的东西:

package example

object App extends Application {
  val x: TriOption[String] = TriUnknown

  x match {
    case TriSome(s) => println("found: " + s)
    case TriNone => println("none")
    case TriUnknown => println("unknown")
  }
}

sealed abstract class TriOption[+A]
final case class TriSome[+A](x: A) extends TriOption[A]
final case object TriNone extends TriOption[Nothing]
final case object TriUnknown extends TriOption[Nothing]
于 2009-11-15T20:39:02.963 回答
9

不要告诉任何人我的建议,但您始终可以将 null 用于 Unknown 而不是编写新类。

car.radioType match { 
   case null => 
   case None => 
   case Some(radioType : RadioType) => 
}
于 2009-11-16T01:26:43.893 回答
5

您可以从 Lift: the Box 中获取一些东西。它具有三种状态,Full、Failure 和 Empty。此外,Empty 和 Failure 都继承自 EmptyBox。

于 2009-11-15T23:27:55.957 回答
4

您可以使用 scala.Either。使用 Left 表示异常值,使用 Right 表示期望值,在这种情况下可以是 Option :

scala> type Result = Either[String, Option[String]]
defined type alias Result

scala> val hasValue: Result = Right(Some("pioneer"))
hasValue: Result = Right(Some(pioneer))

scala> val noValue: Result = Right(None)
noValue: Result = Right(None)

scala> val unknownValue = Left("unknown")
unknownValue: Left[java.lang.String,Nothing] = Left(unknown)
于 2009-11-15T17:03:15.417 回答
2

您可以通过这三种可能性创建自己的。或者作为你的 car.radioType 类型之一,你可能不知道,然后在你的箱子上使用警卫来处理它。如果你自己滚动,你也应该包含 Product trait。liftweb 具有 Box 类型,这是一个关闭选项,允许发生满、空和错误。

于 2009-11-15T16:56:39.227 回答
0

我做了类似的事情来分类给定文件中的 3 种类型的行,例如,给定的行可能Float是标题行、Long中间(行)的行或String尾行。另外isHeader,isRowisTrailer 可以用来知道是哪一个。希望有帮助:

sealed abstract class HRT[+H, +R, +T] {
  val isHeader: Boolean
  val isRow: Boolean
  val isTrailer: Boolean
}

final case class Header[+H, +R, +T](h: H) extends HRT[H, R, T] {
  override val isHeader: Boolean = true
  override val isRow: Boolean = false
  override val isTrailer: Boolean = false
}

final case class Row[+H, +R, +T](r: R) extends HRT[H, R, T] {
  override val isHeader: Boolean = false
  override val isRow: Boolean = true
  override val isTrailer: Boolean = false
}

final case class Trailer[+H, +R, +T](t: T) extends HRT[H, R, T] {
  override val isHeader: Boolean = false
  override val isRow: Boolean = false
  override val isTrailer: Boolean = true
}

object Demo {
  def getEntries(): Seq[HRT[Float, Long, String]] =
    List(
      Header(3.14f),
      Row(42),
      Trailer("good bye")
    )

  val entries = getEntries()

  entries.foreach {
    case Header(f) => printf("header: %f\n", f)
    case Row(l) => printf("row: %d\n", l)
    case Trailer(s) => printf("trailer: %s\n", s)
  }
}
于 2017-11-30T04:11:46.883 回答