Perbedaan di antara mereka adalah, bahwa a val
dieksekusi ketika didefinisikan sedangkan a lazy val
dieksekusi ketika diakses pertama kali.
scala> val x = { println("x"); 15 }
x
x: Int = 15
scala> lazy val y = { println("y"); 13 }
y: Int = <lazy>
scala> x
res2: Int = 15
scala> y
y
res3: Int = 13
scala> y
res4: Int = 13
Berbeda dengan metode (didefinisikan dengan def
) a lazy val
dieksekusi sekali dan kemudian tidak pernah lagi. Ini bisa bermanfaat ketika operasi membutuhkan waktu lama untuk diselesaikan dan ketika tidak yakin apakah nanti digunakan.
scala> class X { val x = { Thread.sleep(2000); 15 } }
defined class X
scala> class Y { lazy val y = { Thread.sleep(2000); 13 } }
defined class Y
scala> new X
res5: X = X@262505b7 // we have to wait two seconds to the result
scala> new Y
res6: Y = Y@1555bd22 // this appears immediately
Di sini, ketika nilai-nilai x
dan y
tidak pernah digunakan, hanya x
membuang-buang sumber daya yang tidak perlu. Jika kita mengira itu y
tidak memiliki efek samping dan bahwa kita tidak tahu seberapa sering itu diakses (tidak pernah, sekali, ribuan kali) tidak ada gunanya untuk menyatakannya def
karena kita tidak ingin menjalankannya beberapa kali.
Jika Anda ingin tahu bagaimana lazy vals
penerapannya, lihat pertanyaan ini .
Lazy<T>
di .NETFitur ini membantu tidak hanya menunda perhitungan mahal, tetapi juga berguna untuk membangun struktur yang saling bergantung atau siklik. Misalnya ini mengarah ke stack overflow:
Tetapi dengan malas vals berfungsi dengan baik
sumber
Saya mengerti bahwa jawabannya diberikan tetapi saya menulis contoh sederhana untuk membuatnya mudah dipahami untuk pemula seperti saya:
Output dari kode di atas adalah:
Seperti dapat dilihat, x dicetak ketika diinisialisasi, tetapi y tidak dicetak ketika diinisialisasi dengan cara yang sama (saya sengaja mengambil x sebagai var di sini - untuk menjelaskan kapan Anda diinisialisasi). Selanjutnya ketika y dipanggil, itu diinisialisasi serta nilai 'x' terakhir dipertimbangkan tetapi bukan yang lama.
Semoga ini membantu.
sumber
Lazy val paling mudah dipahami sebagai " memo memoized (no-arg)".
Seperti def, val malas tidak dievaluasi sampai dipanggil. Tetapi hasilnya disimpan sehingga doa berikutnya mengembalikan nilai yang disimpan. Hasil memoized mengambil ruang dalam struktur data Anda, seperti val.
Seperti yang telah disebutkan orang lain, kasus penggunaan untuk lazy val adalah menunda perhitungan yang mahal sampai mereka diperlukan dan menyimpan hasilnya, dan untuk menyelesaikan dependensi melingkar tertentu antara nilai.
Valk Malas sebenarnya diimplementasikan lebih atau kurang sebagai def memoized. Anda dapat membaca tentang detail penerapannya di sini:
http://docs.scala-lang.org/sips/pending/improved-lazy-val-initialization.html
sumber
Juga
lazy
berguna tanpa ketergantungan siklik, seperti pada kode berikut:Mengakses
Y
sekarang akan melempar pengecualian pointer nol, karenax
belum diinisialisasi. Namun, berikut ini berfungsi dengan baik:Sunting: yang berikut ini juga akan berfungsi:
Ini disebut "penginisialisasi awal". Lihat pertanyaan SO ini untuk lebih jelasnya.
sumber
Demonstrasi dari
lazy
- sebagaimana didefinisikan di atas - eksekusi ketika didefinisikan vs eksekusi ketika diakses: (menggunakan shell scala 2.12.7)sumber
sumber