繁体   English   中英

Scala PartialFunctions给出匹配错误:奇怪的行为

[英]Scala PartialFunctions giving match error: weird behavior

我正在尝试使用部分函数进行一些验证,让我们以字符串为例:

def isLengthValid: PartialFunction[String, Option[String]] ={
  case s:String if s.length > 5 => Some("Invalid")
}

def isStringValid: PartialFunction[String, Option[String]] ={
  case s: String if s == "valid" => Some("Valid")
}

isLengthValid("valid") orElse isStringValid("valid")

预期输出=> Some(“有效”)

但是我遇到了匹配错误:

scala.MatchError:有效(类java.lang.String的)

任何人都可以帮助解决这里出现的问题,因为根据我的理解, .isDefinedAt是在内部调用的,因此不应该提供matchError

PS忽略输入,这只是一个示例。

您的理解是错误的。 ScalaDocs页面明确指出:“在调用apply ...之前,调用方有责任调用isDefinedAt 。”

您的代码没有调用isDefinedAt ,这会导致异常,因此您必须显式调用它,或者可以使用其他方法在内部隐藏isDefinedAt

Seq("valid") collect (isLengthValid orElse isStringValid)
//res0: Seq[Option[String]] = List(Some(Valid))

Seq("vlad") collect (isLengthValid orElse isStringValid)
//res1: Seq[Option[String]] = List()

如果您将最后一行写为

(isLengthValid orElse isStringValid)("valid")

我怀疑问题是您的版本不符合(isLengthValid.apply("valid")).orElse(isStringValid.apply("valid"))

这意味着apply是在orElse发生之前计算出来的,这意味着将部分函数视为总函数,并且会如Valy Dia的答案所解释的那样抛出匹配错误。 实际上在结果输出上调用了orElse ,而不是局部函数。

错误消息来自第一个表达式isLengthValid

它仅针对长度严格大于5的string定义。因此,当将其应用于长度为5的字符串"valid"时,它将引发MatchError

scala>"valid".length
res5: Int = 5

isLengthValid("valid")
scala.MatchError: valid (of class java.lang.String)

如果方法isLengthValid这种方式定义的( 请注意大于等号),则不会抛出MatchError

def isLengthValid: PartialFunction[String, Option[String]] ={
  case s:String if s.length >= 5 => Some("Invalid")
}

scala>isLengthValid("valid")
res8: Option[String] = Some("Invalid")

原始表达式将返回一个Option

scala>isLengthValid("valid") orElse isStringValid("valid")
res9: Option[String] = Some("Invalid")

您在这里可以做的以及在此问题中所作的解释是改用以下定义:

val isLengthValid = new PartialFunction[String, Option[String]] {
  def isDefinedAt(x: String) = x.length > 5
  def apply(x: String) = Some("Invalid")
}

scala>isLengthValid("valid")
res13: Some[String] = Some("Invalid")

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM