2017-09-20 11 views
0

のは、以下のパッケージ階層について考えてみましょう:1がtestのパッケージオブジェクトに次のコードをお持ちの場合なぜパッケージオブジェクトの暗黙のメンバがサブパッケージから見えるのはなぜですか?

test 
    --foo 
    --Foo.scala 
    --bar 
    --Bar.scala 
    package.scala 

を:

package object test { 
    implicit class Pipe[A](a: A) { 
     def |>[B](f: A => B): B = f(a) 
    } 
} 

その後(パッケージtest.foo中)Foo.scalaにおけるケースクラス:パッケージtest.bar

package test.foo 

case class Foo(i: Int) 

object Foo { 
    2.0 |> math.floor // 1 - Does not compile, package object is not visible 
} 

そして最後にアプリケーション:

package test.bar 

import test.foo.Foo 

object Bar extends App { 

    def plus2(i: Int) = i + 2 
    def plus2(f: Foo) = f.i + 2 
    def plus2(o: Option[Foo]) = o.map(f => Foo(f.i + 2)) 

    println(2 |> plus2) // 2 - Does not compile, package object is not visible 
    println(Foo(2) |> plus2) // 3 - Does compile !? 
    println(Option(Foo(2)) |> plus2) // 4 - Does compile too !? 

} 

最初の2つのコメントは、コンパイルできない行を示しています。これは、パッケージオブジェクトがどのサブパッケージにも表示されないため、予想される動作です。

なぜ3番目と4番目のケースがコンパイルされますか?これらのケースで暗黙の変換が適用されるのはなぜですか?ルートパッケージのクラスを使用していません(Fooはサブパッケージにあり、Optionはパッケージにはありません)。ルートパッケージをインポートしていません。これは、暗黙package objectで定義されたときによって引き起こされる

答えて

0

、これら暗黙は、そのパッケージが付けタイプのために動作します。たとえばあなたのタイプはFooです。

import test._ 
println(2 |> plus2) 
println(Foo(2) |> plus2) 

もっと検索:パッケージは、内部コンパニオンモジュールとクラスとして表現され

注意がパッケージを保持するために

ので、あなたの問題のために、手動でのように、暗黙をインポートすることができますメンバー。したがって、パッケージオブジェクトに定義されたimplicitsは、そのパッケージが接頭辞となる型の暗黙のスコープの一部です。

http://www.scala-lang.org/files/archive/spec/2.12/07-implicits.html

+0

はいあなたは正しい、それは私がやったこと、実際にです!私はこの特定のケースと別の1つの見知らぬ人に興味がありました:もし使用された値が現在Future [Foo]やOption [Foo]などの型であれば、それでも動作しますが、Future/Optionはパッケージの前にありません!私はこのケースを追加するために私の質問を編集します。 – Eaque

関連する問題