【问题标题】:Scala strange method invocation syntaxScala奇怪的方法调用语法
【发布时间】:2015-01-25 04:35:12
【问题描述】:

我浏览了Specs2 快速入门指南,很快发现了一些我不熟悉的语法:

"The 'Hello world' string" should {
 // more stuff here
}

深入 specs2 源代码,我发现 shouldDescribed(s: String) 类的一个方法。此外,Described 似乎在类定义之前以某种方式被实例化(作为方法described?):

implicit def described(s: String): Described = new Described(s)
class Described(s: String) {
  def should(fs: =>Fragment) = addFragments(s, fs, "should")
}

我不明白:

  1. 这个隐式实例化是关于什么的
  2. 这个语法到底是怎么回事:"some string" should { ... }。例如。一个字符串,后跟一个方法调用(天真地,如果 should 是 String 类上的一个方法,这对我来说才有意义。

我实际上刚刚遇到了这个似乎回答了我的问题的模式:Pimp my Library 模式利用了我不熟悉的这种隐式转换模式。保持打开状态以防它遗漏任何重要的见解,并且因为这篇文章是 Odersky 大约 10 年前写的。

【问题讨论】:

  • 结合你的两个问题:如果在类上找不到方法,那么 scala 编译器会尝试找到该类可用的隐式转换,以更改原始对象(在本例中为 String)到另一个具有该方法的类(在本例中为Described
  • Scala 中没有隐式实例化。顺便说一句,只有隐式转换和隐式参数。

标签: scala implicit specs2


【解决方案1】:

看起来您已经回答了自己的问题,但我会发布更多详细信息。

“Pimp my Library”的名称已被“Enriched Library”取代(原因可能不需要解释,尽管我承认当我第一次得知 Pimp my Library 时我笑了..)

Scala 中的隐式函数做了 3 件事:

  • 允许从一种类型到另一种类型的隐式转换
  • (凭借上述)允许您以非全局方式安全地扩展现有类。
  • 允许按类型而不是按名称传递值。

隐式扩展方法模式在 Scala 2.10 中更加形式化;您问题中的上述示例可以更简洁地写为隐式值类:

implicit class Described(s: String) {
  def should(fs: =>Fragment) = addFragments(s, fs, "should")
}

我知道编译器会为隐式值类生成更高效的代码,因为它可以跳过包含扩展方法的包装类的分配。见http://www.blog.project13.pl/index.php/coding/1769/scala-2-10-and-why-you-will-love-implicit-value-classes/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-02
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 2013-09-05
    • 2017-12-06
    • 1970-01-01
    相关资源
    最近更新 更多