加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

scala – 获取部分函数的已定义参数

发布时间:2020-12-16 18:38:21 所属栏目:安全 来源:网络整理
导读:说我有一个部分功能(类似于Akka的演员接收方法) def receive: PartialFunction[Any,Unit] = { case SomeCaseClass(params) = println("whatever")} 有没有办法获得这个函数的所有定义参数? 我正在实现类似JSON RPC的服务结构.我基本上希望客户能够定义 通过
说我有一个部分功能(类似于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))

这种方法的一系列缺点显然包括以下内容:

>必须知道消息类型
>如果服务在多个维度中是部分的,则必须也知道所有可能的消息内容
>使用实例Hello(“*”)来表示Hello的任意实例,这使得无法区分接受Hello(_)的服务和实际上只接受Hello(“*”)的服务

如果您使用宏或反射(或魔术)找到真正的解决方案,请在此处发布!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读