何时是从伴随对象导入的隐式?

时间:2014-07-15 06:33:51

标签: scala implicit-conversion implicit companion-object

我知道这是无数的暗示/伴侣对象问题。但是,我还没有在任何地方找到这个的情况。

在“Tryout”中,为什么A不需要导入隐式类,而B确实需要它? Thankx。

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))
}

1 个答案:

答案 0 :(得分: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 =>的范围。长。

函数[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)问题”

当你这么说时,显而易见。

另请参阅“参数类型的隐含范围”下的enter link description here