5

我偶尔会遇到以下模式,我基本上有 a PartialFunction[SomeType,AnotherType],并希望将其视为 a Function[SomeType,Option[AnotherType],例如:

def f(s:SomeType):Option[AnotherType] = s match {
  case s1:SubType1 => Some(AnotherType(s1.whatever))
  case s2:SubType2 => Some(AnotherType(s2.whatever))
  case _ => None
}

有没有办法以一种避免默认情况并将结果包装在定义位置的方式编写上述函数Some?到目前为止,我想出的最好的是:

def f(s:SomeType):Option[AnotherType] = pf.lift(s)
def pf:PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

有没有办法在不定义中间函数的情况下做到这一点?我已经按照以下方式尝试了各种方法,但还没有任何东西可以编译:

def f:Function[SomeType,Option[AnotherType]] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}.lift
4

2 回答 2

7

condOpt在对象 scala.PartialFunction 中。从斯卡拉多克:

def onlyInt(v: Any): Option[Int] = condOpt(v) { case x: Int => x }
于 2011-01-18T07:50:52.647 回答
4

与其说是答案,不如说是解释为什么 huynhjl 的答案是正确的......

您的部分困惑是您正在尝试def使用部分功能。所有这一切都是创建一个返回PartialFunction对象的方法,当您还不如直接创建事物时:

val pf: PartialFunction[SomeType,AnotherType] = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
}

虽然我个人更喜欢使用类型归属:

val pf = {
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]

无论哪种方式,您都必须指定输入类型是什么,因此您必须给出PartialFunction. 我知道感觉应该可以推断出这一点,但遗憾的是,事实并非如此!

使用归属版本,您可以在同一个地方定义和提升所有内容:

val pf = ({
  case s1:SubType1 => AnotherType(s1.whatever)
  case s2:SubType2 => AnotherType(s2.whatever)
} : PartialFunction[SomeType,AnotherType]).lift

PartialFunction.condOpt不过是更好的解决方案,因为它允许推理器为您完成大部分工作,留下更清晰的代码:)

于 2011-01-18T10:13:15.917 回答