これは、Java ライブラリと対話する場合、Scala は Java の静的メソッドを Scala のシングルトン オブジェクトにマップする方法を必要とするためです。
たとえば、次の Java クラスがあるとします。
package pkg;
class Test {
public static void printHello() {
System.out.println("Hello");
}
}
printHello
Scala でどのように呼び出すことができますか? 次のようになります。
import pkg.Test
Test.printHello()
ご覧のとおり、構文は でメソッドを呼び出すのとまったく同じobject Test
です。この観点から、シングルトンはすでに定義されており、同じ FQN で を 2 回Test
定義することはできません。object
pkg.matchers.Test
そのため、と競合しないように定義する必要がありますpkg.Test
。
そして、Scala のコンパイラは、それがキーワードpkg.matchers.Test
を使用して構築できなかったシングルトンであることを理解するほどスマートです。これが、コード例で同時に使用できる理由です。new
new Test(1)
pkg.Test
pkg.matchers.Test
実際、まったく必要ありませんtype Test = pkg.Test
。以下は正常に機能しています。
package pkg
package matchers {
object Test {
def unapply(t : Test) : Option[Int] = Some(t.v)
}
}
object main {
import pkg.matchers._
def main(args : Array[String]) {
val t = new Test(1)
t match {case Test(v) => println(v)}
println(t.v)
}
}
アップデート
Extractor はコンパニオン オブジェクトである必要はありません。つまり、対応するクラスは必要ありません。withメソッドはエクストラクタとして機能しますobject
。unapply
object StringLength {
def unapply(x: String): Option[Int] = Some(x.length)
}
object Main {
def main(args: Array[String]) {
"Hello World" match {
case StringLength(x) => println("length:" + x)
}
}
}
したがって、メイン メソッドが にないpkg
場合は、次の選択肢があります。
エクストラクタの名前を別の名前に変更して、コンパイラがエクストラクタを使用していることを認識できるようにします。
FQN を使用すると、コンパイラpkg.matchers.Test
はpkg.Test
.
package pkg.matchers {
import pkg._
object Test {
def unapply(t : Test) : Option[Int] = Some(t.v)
}
}
object Main {
def main(args: Array[String]) {
import pkg.Test
val t = new Test(1)
t match {case pkg.matchers.Test(v) => println(v)}
println(t.v)
}
}
構文と競合しないように、pkg.Test
別の名前に名前を変更します。import
pkg.matchers.Test
object Main {
def main(args: Array[String]) {
import pkg.{Test => JTest}
import pkg.matchers.Test
val t = new JTest(1)
t match {case Test(v) => println(v)}
println(t.v)
}
}
pkg
import 特にを使用して、からすべてをインポートするだけpkg.matcher.Test
です。
def main(args: Array[String]) {
import pkg._
import pkg.matchers.Test
val t = new Test(1)
t match {case Test(v) => println(v)}
println(t.v)
}