0

我知道这是无数隐含/伴随对象问题。但是,我还没有在任何地方找到这个案例。

在“Tryout”中,为什么 A 不需要为隐式类导入,而 B 却需要呢?谢谢。

class LongConsumer {
  def consume(l: Long) = Unit
}

case class X(x: Long)

object X extends (Long => X) {
  implicit class ConsumeX(val c: LongConsumer) extends AnyVal {
    def consume(x: X) = c consume x.x
  }
  implicit class EatX(val c: LongConsumer) extends AnyVal {
    def eat(x: X) = c consume x.x
  }
}

object Tryout {
  // A: does not need import to compile - why?
  new LongConsumer().consume(X(10L))

  // B: needs import to compile - why?
  import X.EatX
  new LongConsumer().eat(X(10L))
}
4

1 回答 1

1

视图只有三种情况。

http://www.scala-lang.org/files/archive/spec/2.11/07-implicit-parameters-and-views.html#views

您的案例 A 是 #1,其中 X 不是 Long,正如消费者所期望的那样。(编辑:对不起,我在看 Hulu。它是 #3,其中不适用消耗。转换是从 LongConsumer 到 ConsumeX。在这种情况下,我不会期望 X 的隐含范围起作用。 )

但请注意,隐式范围是 X => Long 的范围。

Function[X, Long] 的范围包括两个类型参数的范围,而 X 的范围包括伴随的 X。(上一节 7.2 列出了隐式范围内的内容。)直觉是你有一个类型在手,但需要另一个;任何一种类型都可以提供转换。

在您的案例 B 中,它是案例 #2,并且 LongConsumer 的范围不提供转换。

我在 ML 上要求澄清。-Ytyper-debug说这是第二次尝试。

|    |    second try: (l: Long)Unit.type and eatery.X.type
|    |    |-- eatery.X.type EXPRmode (silent: value <local Tryout> in Tryout)
|    |    |    |-- X.apply BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Tryout> in Tryout)
|    |    |    |    \-> (x: Long)eatery.X
|    |    |    \-> eatery.X
|    |    |-- eatery.this.X.ConsumeX BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Tryout> in Tryout) implicits disabled
|    |    |    \-> eatery.X.ConsumeX.type <and> (c: eatery.LongConsumer)eatery.X.ConsumeX
|    |    |-- (c: eatery.LongConsumer)eatery.X.ConsumeX EXPRmode-POLYmode-QUALmode (site: value <local Tryout> in Tryout)
|    |    |    \-> eatery.X.ConsumeX
|    |    |-- eatery.this.X.ConsumeX(new LongConsumer()).consume BYVALmode-EXPRmode-FUNmode-POLYmode (silent: value <local Tryout> in Tryout)
|    |    |    \-> (x: eatery.X)Unit.type (with underlying type (x: eatery.X)Unit.type)
|    |    \-> Unit.type
|    \-> [object Tryout] eatery.Tryout.type

结果在:

https://issues.scala-lang.org/browse/SI-5089

@retronym 说:为什么隐式范围包括应用程序的参数类型的同伴的更广泛的问题被称为“1 + BigInteger(1) 问题”

当你这样说时,有点明显。

另请参阅“参数类型的隐式范围”下的输入链接描述。

于 2014-07-15T07:09:02.553 回答