scala – 获取部分函数的已定义参数
说我有一个部分功能(类似于Akka的演员接收方法)
def receive: PartialFunction[Any,Unit] = { case SomeCaseClass(params) => println("whatever") } 有没有办法获得这个函数的所有定义参数? 我正在实现类似JSON RPC的服务结构.我基本上希望客户能够定义 def clientService = { case Connect(login,password) =>..... case SomeMessage => ... case SomeMethod(bla) => .. } 例如第一种方法将从中翻译出来 {method: "connect",params:{login: "asdsad",password: "adsada"}} (此部分已经有效) 现在,如果客户端已经定义了服务而另一个客户端想知道服务的可用方法,我现在需要知道服务接受哪种类型的案例类,以便我可以告诉请求的客户端.我知道我可以使用对象中的常规方法轻松完成此操作,但由于我解析JSON并将其转换为case类,部分函数将简化我的API并且我喜欢漂亮的代码;) 另外我很确定必须有一种通过反射的方法,虽然我不知道在编译/运行后如何表示部分函数. 解决方法
根据您可以或愿意对您的服务做出多少假设,这是一个完全不复杂的方法,可能仍然是一个选项.它基本上依赖于1)所有可能的消息类型是已知的,并且b)部分函数仅在一个维度中是部分的(稍后更多).
我们需要一组有限的可能消息类型: sealed trait Message case class Hello(who: String) extends Message case class Lunch(withWhom: String) extends Message case class Dinner(withWhom: String) extends Message case class Goodbye(who: String) extends Message 以及一些示例服务: val service0: PartialFunction[Any,Unit] = { case Hello(who) => () case Goodbye(who) => () } val service1: PartialFunction[Any,Unit] = { case Hello(who) => () case Lunch(withWhom) => () case Goodbye(who) => () } var services = List(service0,service1) 接下来,我们还定义了一个消息实例列表,用作接收消息的蓝图: val simpleInstances = List(Hello("*"),Lunch("*"),Dinner("*"),Goodbye("*")) 最后,我们定义一个方法,该方法返回部分函数和可能参数列表中的接受参数: def supportedArguments[F,T,A <: F] (pf: PartialFunction[F,T],args: Iterable[A]) = args filter pf.isDefinedAt 漂亮的打印机: def printSupportedArguments(services: Iterable[PartialFunction[Any,Unit]],messages: Iterable[Message]) { services.zipWithIndex.foreach {case (s,i) => val supported = supportedArguments(s,messages) println(s"Service $i supports $supported") } } 我们走吧: printSupportedArguments(services,simpleInstances) // Service 0 supports List(Hello(*),Goodbye(*)) // Service 1 supports List(Hello(*),Lunch(*),Goodbye(*)) // Service 2 supports List(Goodbye(*)) 如果服务不仅局限于他们接受的消息类型,而且对于他们接受的消息内容,也就是说,如果它们在多个方向上是部分的,那么事情会变得更加复杂: val service2: PartialFunction[Any,Unit] = { case Hello("Thomas") => () case Hello("Laura") => () case Goodbye(who) => () } 这样的服务还需要调整蓝图实例列表: val moreInstances = simpleInstances ++ List(Hello("Thomas"),Hello("Laura")) 导致: printSupportedArguments(services :+ service2,moreInstances) // Service 0 supports List(Hello(*),Goodbye(*),Hello(Thomas),Hello(Laura)) // Service 1 supports List(Hello(*),// Hello(Laura)) // Service 2 supports List(Goodbye(*),Hello(Laura)) 这种方法的一系列缺点显然包括以下内容: >必须知道消息类型 如果您使用宏或反射(或魔术)找到真正的解决方案,请在此处发布! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |