[英]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.