Scala,部分功能

aio*_*obe 8 scala pattern-matching extractor partialfunction

有没有办法PartialFunction通过case声明创建一个除外?

我很好奇,因为我想表达以下内容(scala pseudo ahead!)...

val bi = BigInt(_)
if (bi.isValidInt) bi.intValue
Run Code Online (Sandbox Code Playgroud)

......作为一个部分功能,并做

val toInt : PartialFunction[String, Int] = {
    case s if BigInt(s).isValidInt => BigInt(s).intValue
}
Run Code Online (Sandbox Code Playgroud)

因为我创造了BigInt两次似乎是多余的.

0__*_*0__ 5

不确定我理解这个问题.但这是我的尝试:为什么不创建一个提取器?

object ValidBigInt {
  def unapply(s: String): Option[Int] = {
    val bi = BigInt(s)
    if (bi.isValidInt) Some(bi.intValue) else None
  }
}

val toInt: PartialFunction[String, Int] = {
  case ValidBigInt(i) => i
}
Run Code Online (Sandbox Code Playgroud)

另一种选择是(并且可以回答关于是否可以创建PartialFunctioncase文字之外的其他问题):

val toInt = new PartialFunction[String, Int] {
  def isDefinedAt(s: String) = BigInt(s).isValidInt
  def apply(s: String) = BigInt(s).intValue
}
Run Code Online (Sandbox Code Playgroud)

然而,由于部分函数的想法是它只是部分定义,最终你仍然会做多余的事情 - 你需要创建一个大的int来测试它是否有效,然后在函数应用程序中创建大的int再次...

我在Github看到一个项目试图通过稍微缓存结果来解决这个问题isDefinedAt.如果你进入基准测试,你会发现它比默认的Scala实现要慢:)

因此,如果你想要绕过isDefinedAtvs 的双重性质apply,你应该直接选择一个提供Option[Int]结果的(完整)函数.