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

ビューには 3 つのケースしかありません。

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-debug2度目の挑戦だそうです。

|    |    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 に答える