1. ホーム
  2. scala

[解決済み] パッケージオブジェクト

2023-02-13 17:47:13

質問

パッケージオブジェクトとは何でしょうか?

サンプルを動作させようとしたところ、以下のような形でしか動作しませんでした。

package object investigations {
    val PackageObjectVal = "A package object val"
}

package investigations {

    object PackageObjectTest {
        def main(args: Array[String]) {
            println("Referencing a package object val: " + PackageObjectVal)
        }
    }
}

今までの観察では

package object _root_ { ... }

は許可されません(これは合理的です)。

package object x.y { ... }

も禁止されています。

パッケージオブジェクトは直系の親パッケージで宣言する必要があるようで、上記のように書くと、ブレースで区切られたパッケージ宣言形式が必要です。

これらは一般的に使用されているのでしょうか?もしそうなら、どのように?

どのように解決するのですか?

通常、パッケージ・オブジェクトを別のファイルである package.scala という別のファイルに置きます。ネストされたパッケージ構文を使うこともできますが、これはかなり珍しいことです。

パッケージオブジェクトの主な用途は、パッケージ内の様々な場所で定義が必要な場合と、パッケージによって定義されたAPIを使用する際にパッケージの外側で定義が必要な場合です。以下はその例です。

// file: foo/bar/package.scala

package foo

package object bar {

  // package wide constants:
  def BarVersionString = "1.0"

  // or type aliases
  type StringMap[+T] = Map[String,T]

  // can be used to emulate a package wide import
  // especially useful when wrapping a Java API
  type DateTime = org.joda.time.DateTime

  type JList[T] = java.util.List[T]

  // Define implicits needed to effectively use your API:
  implicit def a2b(a: A): B = // ...

}

これで、そのパッケージオブジェクトの中の定義が、パッケージ全体で利用できるようになりました。 foo.bar . さらに、そのパッケージの外からインポートされた定義もインポートされます。 foo.bar._ .

この方法により、あなたのライブラリを効果的に使用するために、APIクライアントに追加のインポートを要求することを防ぐことができます - 例えば、scala-swingでは、次のように記述する必要があります。

import swing._
import Swing._

のように、すべての良さを持つように onEDT からの暗黙の変換と Tuple2 から Dimension .