gpt4 book ai didi

scala - 如何避免在模式匹配保护中显式调用 .isDefinedAt()

转载 作者:行者123 更新时间:2023-12-04 05:03:45 24 4
gpt4 key购买 nike

我有一些基于 Akka 的角色系统,其中多种角色基于相同的模板,因为这些角色仅因响应值类型而异。例如:

final case class Request(data: Any)
final case class Response(data: Any)

abstract class ActorTemplate[T] extends Actor {
def dataFunction: PartialFunction[Any, T]

def respond(data: T): Response

def receive: Receive = {
case Request(data) if dataFunction.isDefinedAt(data) =>
sender ! respond(dataFunction(data))
}
}

部分函数有一种方法可以避免类型删除,这使我无法简单

  def receive: Receive = {
case Request(data: T) =>
sender ! respond(data)

同时强制我生产 if dataFunction.isDefinedAt(data)守卫模式,我只是不太喜欢它。

有没有办法避免显式保护?

我现在找到的唯一方法是引入一些愚蠢的提取器:

object DataExtractor {
def unapply(data: Any): Option[T] =
if (dataFunction.isDefinedAt(data)) Some(dataFunction(data)) else None
}

def receive: Receive = {
case Request(DataExtractor(data) =>
sender ! respond(data)

但也许它已经在标准库中的某个地方完成了?或者也许还有其他类似于集合的方式 collect方法,但为了匹配?

结论

经过一番思考后,我又回到了提取器对象,并在@pagoda_5b 建议的帮助下将其移动到了 trait 中:
trait PFExtract[T] {
object PF {
def unapply(any: Any)(implicit pf: PartialFunction[Any, T]): Option[T] =
pf.lift(any)
}
}

最佳答案

我实际上会做的是使用 applyOrElse方法在 dataFunction , 当未为给定输入定义偏函数时定义默认响应

def defaultAnswer: T

def receive: Receive = {
case Request(data) =>
sender ! respond(dataFunction.applyOrElse(data, defaultAnswer))
}

如果您更喜欢将答案包含在 Option 中,已经有一个方法叫 lift正如你正确猜到的那样,它为你做到了
def receive: Receive = {
case Request(data) =>
sender ! respond(dataFunction.lift(data))
}

如果函数不是为数据定义的,你甚至可以决定不回答
def receive: Receive = {
case Request(data) =>
dataFunction.lift(data).foreach {
sender ! respond(_)
}
}
foreachOption 上定义仅当有一些内容可用时(即,如果您有 Some(...) ), type 才会在闭包中运行代码

关于scala - 如何避免在模式匹配保护中显式调用 .isDefinedAt(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15786328/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com