【问题标题】:implicits for objects in ScalaScala中对象的隐式
【发布时间】:2013-03-08 01:31:34
【问题描述】:

我对 Joshua Suareth 的书 Scala 深入研究第 100 页的“5.1.3 隐式解析”中的描述感到困惑:

Scala 对象不能有隐含的伴随对象。因为 this,与对象类型相关的隐式,需要 该对象类型的隐式范围,必须从 外范围。这是一个例子:

scala> object Foo {
     |   object Bar { override def toString = "Bar" }
     |   implicit def b : Bar.type = Bar 
     |}
defined module Foo
scala> implicitly[Foo.Bar.type]
res1: Foo.Bar.type = Bar

但是当我在 REPL 中隐含对象 Bar 时:

scala> object Foo {
     |   implicit object Bar {
     |     override def toString = "isBar" }
     | }
defined module Foo
scala> implicitly[Foo.Bar.type]
res0: Foo.Bar.type = isBar

似乎不需要在外部范围内定义一个隐式。还是我完全误解了约书亚的意思?

【问题讨论】:

  • 这本书是什么时候写的,你用的是什么版本的 Scala?这可能在 2.9 或 2.10 中有所改变。
  • 至少从 2.9.x 开始,情况与我的回答一样。 Josh 一定是指 Scala pre-2.9,或者只是不知道语义。 FTR 当我发现这是可能的时候,我既惊讶又高兴。
  • 感谢您的回复。本书建议它涵盖 2.7.x 到 2.9.x。我的机器上安装了 2.10,它的行为可能会有所不同。

标签: scala object implicit


【解决方案1】:

在这种情况下,对象就像它们自己的同伴一样,因此您只需将提及对象类型的隐式嵌套在对象本身的主体中,

scala> object Bar {
     |   override def toString = "Bar"
     |   implicit def b : Bar.type = Bar
     | }
defined module Bar

scala> implicitly[Bar.type]
res0: Bar.type = Bar

请注意,这里Bar 的主体已被视为解析Bar.type 的隐式范围的一部分。

这似乎是 Scala 类型系统的一个不起眼的角落,但我能够在 shapelesspolymorphic (function) values 编码中很好地使用它。

【讨论】:

    【解决方案2】:

    如果您将以下代码放入文件中并尝试使用scalac 进行编译,则会失败并显示'implicit' modifier cannot be used for top-level objects

     implicit object Foo {
      object Bar { override def toString = "Bar" }
     }
    

    然而,这编译得很好:

     object Foo {
      implicit  object Bar { override def toString = "Bar" }
     }
    

    我相信使用 REPL implicit's 并不完全是顶级的,因此看起来不一致。

    【讨论】:

      猜你喜欢
      • 2016-01-23
      • 2018-02-01
      • 1970-01-01
      • 2014-10-24
      • 1970-01-01
      • 1970-01-01
      • 2020-11-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多