Upload page content

You can upload content for the page named below. If you change the page name, you can also upload content for another page. If the page name is empty, we derive the page name from the file name.

File to load page content from
Page name
Comment

Locked History Actions

scala/packageObjects

パッケージオブジェクト

パッケージオブジェクトの簡単な利用方法

パッケージオブジェクトが無い場合(2.7まで)

すべてをクラス(オブジェクト)の中で定義するしかない。

package foo
object Foo {
  type MOJI = String
  val SomeString = "hello world"
}
....
....
import foo.Foo._
object Sample {
  def main(args: Array[String]) {
    val a:MOJI = "Greeting:"
    println(a + SomeString)
  }
}

上例では、例えばStringのエイリアスとしてMOJIを使いたいのだが、それはFooというオブジェクトの中に定義し、それを「import foo.Foo._」としてから使うしかない。

パッケージオブジェクトのある場合(2.8以降)

あたかもパッケージに直接記述できるかのようになる。

package object foo {
  type MOJI = String
  val SomeString = "hello world"
}
...
...
import foo._
object Sample {
  def main(args: Array[String]) {
    val a:MOJI = "Greeting:"
    println(a + SomeString)
  }
}

importする場合は、もはやクラス(オブジェクト)を指定する必要はなく、「import foo._」でよい。 もちろん、typeやvalだけでなく、defも書ける(はず)。

何の役に立つのか?

  • 上例からも明らかなように、クラスを指定しなくともその機能が使用できる。ここにはパッケージ全体で共通の定義等を置いておくことができる。でもこれだけでは「素晴らしく便利」とは言えない。
  • 例えば、クラスのパッケージを移動したいが後方互換性を残しておきたい場合。

例えば、パッケージfooにBarというクラスがあったとする。

package foo
class Bar {
}

これを、some.whereというパッケージに移動したいのだが、単純に移動すると、foo.Barを使用中のユーザは困ってしまう。 そこで、Barをsome.whereに移すと同時に、パッケージオブジェクトfooとして次のような定義を行う。

package object foo {
  type Bar = some.where.Bar
}

こうして、後方互換性が保たれるという仕組み。

パッケージオブジェクトは「オブジェクト」

パッケージオブジェクトは「オブジェクト」なので、普通のオブジェクトと同様に継承等ができてしまう。

package foo {
  class Class {
    type NUMBER = Int
  }
}
package object foo extends Class {
  type MOJI = String
  val SomeString = "hello world"
}
....
import foo._
object Sample {
  def main(args: Array[String]) {
    val a:MOJI = "Greeting:"
    val n:NUMBER = 1
    println(a + SomeString + n)
  }
}