Apa objek paket, bukan begitu banyak konsepnya tetapi penggunaannya?
Saya sudah mencoba untuk mendapatkan contoh bekerja dan satu-satunya bentuk saya harus bekerja adalah sebagai berikut:
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)
}
}
}
Pengamatan yang saya lakukan sejauh ini adalah:
package object _root_ { ... }
tidak diizinkan (yang masuk akal),
package object x.y { ... }
juga tidak diizinkan.
Tampaknya objek paket harus dideklarasikan dalam paket induk langsung dan, jika ditulis seperti di atas, diperlukan formulir deklarasi paket yang dipisahkan tanda kurung kurawal.
Apakah mereka umum digunakan? Jika ya, bagaimana caranya?
Jawaban:
Biasanya Anda akan meletakkan objek paket Anda dalam file terpisah yang disebut
package.scala
dalam paket yang sesuai dengannya. Anda juga dapat menggunakan sintaks paket bersarang tetapi itu sangat tidak biasa.Kasus penggunaan utama objek paket adalah saat Anda membutuhkan definisi di berbagai tempat di dalam paket Anda serta di luar paket saat Anda menggunakan API yang ditentukan oleh paket. Berikut ini contohnya:
// 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 = // ... }
Sekarang definisi di dalam objek paket itu tersedia di dalam keseluruhan paket
foo.bar
. Selanjutnya definisi diimpor ketika seseorang di luar impor paket itufoo.bar._
.Dengan cara ini Anda dapat mencegah agar klien API mengeluarkan impor tambahan untuk menggunakan perpustakaan Anda secara efektif - misalnya dalam scala-swing Anda perlu menulis
import swing._ import Swing._
untuk memiliki semua kebaikan
onEDT
dan konversi implisit dariTuple2
menjadiDimension
.sumber
org
ataucom
tingkat atas dengan objek paket Anda jika Anda menginginkannya untuk dimiliki oleh paket root Anda sendiri misalnyaorg.foo
. Saya menemukan bahwa mengizinkan definisi untuk berada langsung di bawah paket yang seharusnya menjadi bagian dari - akan menjadi antarmuka api bahasa yang sedikit lebih tepat.Sementara jawaban Moritz tepat, satu hal tambahan yang perlu diperhatikan adalah objek paket adalah objek. Antara lain, ini berarti Anda dapat membangunnya dari sifat-sifat, menggunakan warisan campuran. Contoh Moritz dapat ditulis sebagai
package object bar extends Versioning with JodaAliases with JavaAliases { // package wide constants: override val version = "1.0" // or type aliases type StringMap[+T] = Map[String,T] // Define implicits needed to effectively use your API: implicit def a2b(a: A): B = // ... }
Di sini Versioning adalah sifat abstrak, yang mengatakan bahwa objek paket harus memiliki metode "versi", sedangkan JodaAliases dan JavaAliases adalah sifat konkret yang berisi alias tipe praktis. Semua ciri ini dapat digunakan kembali oleh banyak objek paket yang berbeda.
sumber
Anda bisa melakukan lebih buruk daripada langsung ke sumbernya. :)
https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/library/scala/package.scala
https://lampsvn.epfl.ch/trac/scala/browser/scala/trunk/src/library/scala/collection/immutable/package.scala
sumber
Tidak demikian halnya dengan Scala 3 yang rencananya akan dirilis pertengahan tahun 2020, berdasarkan Dotty , seperti di sini :
package p type Labelled[T] = (String, T) val a: Labelled[Int] = ("count", 1) def b = a._2 def hello(name: String) = println(i"hello, $name)
sumber