Ini gula sintaksis untuk skrip dasar. Menghilangkan kata kunci "def" menempatkan variabel di binding untuk skrip saat ini dan asyik memperlakukannya (kebanyakan) seperti variabel cakupan global:
x = 1
assert x == 1
assert this.binding.getVariable("x") == 1
Sebaliknya, menggunakan kata kunci def tidak menempatkan variabel dalam binding skrip:
def y = 2
assert y == 2
try {
this.binding.getVariable("y")
} catch (groovy.lang.MissingPropertyException e) {
println "error caught"
}
Cetakan: "kesalahan tertangkap"
Menggunakan kata kunci def dalam program yang lebih besar adalah penting karena ini membantu menentukan ruang lingkup di mana variabel dapat ditemukan dan dapat membantu menjaga enkapsulasi.
Jika Anda mendefinisikan metode dalam skrip Anda, itu tidak akan memiliki akses ke variabel yang dibuat dengan "def" di tubuh skrip utama karena mereka tidak dalam ruang lingkup:
x = 1
def y = 2
public bar() {
assert x == 1
try {
assert y == 2
} catch (groovy.lang.MissingPropertyException e) {
println "error caught"
}
}
bar()
mencetak "kesalahan tertangkap"
Variabel "y" tidak berada dalam ruang lingkup di dalam fungsi. "x" berada dalam ruang lingkup karena groovy akan memeriksa binding skrip saat ini untuk variabel. Seperti yang saya katakan sebelumnya, ini hanyalah gula sintaksis untuk membuat skrip cepat dan kotor lebih cepat untuk mengetik (sering satu baris).
Praktik yang baik dalam skrip yang lebih besar adalah selalu menggunakan kata kunci "def" sehingga Anda tidak mengalami masalah pelingkupan yang aneh atau mengganggu variabel yang tidak Anda inginkan.
new FileInputStream('Test.groovy').getChannel()
tanpa impor?Menurut halaman ini ,
def
adalah pengganti untuk nama jenis dan hanya dapat dianggap sebagai alias untukObject
(yaitu menandakan bahwa Anda tidak peduli dengan jenisnya).sumber
Sejauh menyangkut naskah tunggal ini, tidak ada perbedaan praktis.
Namun, variabel yang didefinisikan menggunakan kata kunci "def" diperlakukan sebagai variabel lokal, yaitu lokal untuk skrip yang satu ini. Variabel tanpa "def" di depannya disimpan dalam apa yang disebut binding setelah digunakan pertama kali. Anda dapat menganggap pengikatan sebagai area penyimpanan umum untuk variabel dan penutupan yang harus tersedia skrip "antara".
Jadi, jika Anda memiliki dua skrip dan menjalankannya dengan GroovyShell yang sama, skrip kedua akan bisa mendapatkan semua variabel yang ditetapkan dalam skrip pertama tanpa "def".
sumber
Alasan untuk "def" adalah untuk memberi tahu groovy bahwa Anda bermaksud membuat variabel di sini. Ini penting karena Anda tidak ingin membuat variabel secara tidak sengaja.
Ini agak dapat diterima dalam skrip (skrip Groovy dan groovysh memungkinkan Anda untuk melakukannya), tetapi dalam kode produksi itu adalah salah satu kejahatan terbesar yang dapat Anda temui yang mengapa Anda harus mendefinisikan variabel dengan def dalam semua kode groovy aktual (apa pun di dalam kelas).
Inilah contoh mengapa itu buruk. Ini akan berjalan (Tanpa gagal menegaskan) jika Anda menyalin kode berikut dan menempelkannya ke groovysh:
Masalah seperti ini bisa membutuhkan banyak waktu untuk menemukan dan memperbaikinya - Bahkan jika itu hanya menggigit Anda sekali dalam hidup Anda, masih akan memakan waktu lebih banyak daripada secara eksplisit mendeklarasikan variabel ribuan kali sepanjang karier Anda. Itu juga menjadi jelas bagi mata di mana itu dinyatakan, Anda tidak perlu menebak.
Dalam input skrip / konsol yang tidak penting (seperti konsol asyik) itu agak dapat diterima karena ruang lingkup skrip terbatas. Saya pikir satu-satunya alasan groovy memungkinkan Anda melakukan ini dalam skrip adalah untuk mendukung DSL seperti halnya Ruby (trade-off yang buruk jika Anda bertanya kepada saya, tetapi beberapa orang menyukai DSL)
sumber
Sebenarnya, saya tidak berpikir itu akan berperilaku sama ...
variabel dalam Groovy masih memerlukan deklarasi, hanya saja deklarasi TYPED, karena sisi kanan umumnya berisi informasi yang cukup untuk Groovy untuk mengetik variabel.
Ketika saya mencoba menggunakan variabel yang belum saya deklarasikan dengan def atau tipe, saya mendapatkan kesalahan "Tidak ada properti seperti itu", karena mengasumsikan bahwa saya menggunakan anggota kelas yang berisi kode.
sumber