Scala 奇怪的方法调用语法

Scala strange method invocation syntax

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

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

深入研究 specs2 源代码,我发现 should 是 class Described(s: String) 的一个方法。此外,Described 似乎以某种方式实例化(作为一种方法 described?)隐含地就在 class 定义之前:

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 是字符串 class.
  3. 上的一个方法,这对我来说天真地有意义

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

看起来你已经回答了你自己的问题,但我会 post 更多细节。

"Pimp my Library" 名称已被替换为 "Enriched Library"(出于可能不需要解释的原因,尽管我承认当我第一次知道拉皮条图书馆时我笑了......)

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

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

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

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

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