【问题标题】:What's the meaning of: 'request => out => ' in Play FrameworkPlay Framework中的'request => out =>'是什么意思
【发布时间】:2015-06-26 16:03:18
【问题描述】:

当我深入研究 Play Framework 2 参考文档时,我发现了有关 WebSockets 的以下语法:

def socket = WebSocket.acceptWithActor[String, String] { request => out =>
  MyWebSocketActor.props(out)
}

https://www.playframework.com/documentation/2.3.x/ScalaWebSockets

但我无法理解这种语法“request => out”的“含义”。我可以从 WebSocket 请求中推断出,我得到了一个名为 out 的 ActorRef,但我想问是否有人可以让我看到与此语法的匹配以及在他们的 API 中找到的方法签名。

我使用 Akka+Scala 开发了一个小型应用程序,所以我知道一些 scala 基本语法。

已解决

查看 Angelo Genovese 和 bjfletcher 的答案。

【问题讨论】:

    标签: scala syntax playframework


    【解决方案1】:
    request ⇒ out ⇒ MyWebSocketActor.props(out)
    

    是一个接受RequestHeader并返回一个接受ActorRef并返回Props的函数的函数

    在您链接的 API 中,这表示为

    f: (RequestHeader) ⇒ (ActorRef) ⇒ Props
    

    以这种方式可视化可能更容易:

    def first(request: RequestHeader) = {
      def second (out: ActorRef) = {
        MyWebSocketActor.props(out)
      }
      second _
    }
    

    【讨论】:

    • 但是当我在做'request => out'时发生了什么?我的意思是, request 和 out 没有在任何地方声明,所以......我正在就地定义函数?我正在尝试将此语法与其中使用的语法相匹配,例如: numberList.foreach { number => println(number) } 但我不确定我是否正确...
    • 你不是在做request => out你在做request => { out => ... }
    • @Daenyth 用 '{ }' 修改了代码,它也可以工作(如您所料),那么第一个语法是语法糖吗?
    • @vicaba 或多或少。它不完全是糖,它是一切都是一种表达这一事实的一个方面。 { ... } 是一个表达式,它产生大括号内任何内容的最后评估的返回值。当内部是单个语句时,您可以(通常)省略它们。
    【解决方案2】:

    查看acceptWithActor的定义:

    def acceptWithActor(f: RequestHeader => HandlerProps)
    

    你看到它接受一个函数参数,它接受一个RequestHeader对象并产生一个HandlerProps对象。

    因此,您的目标是组合一个接受 RequestHeader 的函数:

    request => { ... produce HandlerProps here ... }
    

    现在,你需要返回一个HandlerProps 对象,让我们看看这是什么:

    type HandlerProps = ActorRef => Props
    

    所以,你的下一个目标是接收一个ActorRef 对象并生成一个Props

    request => {
        actorRef => {
            ... produce Props here ...
        }
    }
    

    现在,您需要生成一个Props 对象:

    MyWebSocketActor.props(out)
    

    把它们放在一起,你就有了你的代码。 Play 使用将 actor 引用命名为 out 而不是 actorRef 的约定。

    我希望这会有所帮助。

    更新(见 cmets)

    您确实可以指定类型:

    ....acceptWithActor[String, String] { request: RequestHeader => out: ActorRef => ...
    

    这有时比没有读起来更好。它们不是必需的,因为它们确实是由编译器推断出来的,编译器以与我上面解释的相同方式看待这一切。

    【讨论】:

    • 是的,现在更清楚了。但是我仍然不明白为什么'request'是RequestHeader类型而'out'是ActorRef类型,如果我没有在任何地方指定它或者它是由编译器推断出来的?
    • 您绝对可以将类型添加到请求中。请参阅编辑后的答案。
    • 那就推断出来了,谢谢!抱歉,我可以标记两个正确答案,但我会更新我的问题以澄清这两个答案都是有意义的。
    猜你喜欢
    • 2021-08-03
    • 2021-09-20
    • 1970-01-01
    • 2012-11-27
    • 2011-07-26
    • 1970-01-01
    • 2010-09-12
    • 2017-08-28
    • 2021-02-21
    相关资源
    最近更新 更多