ए def
को ए def
, ए val
, lazy val
या ए में से किसी के द्वारा लागू किया जा सकता है object
। तो यह एक सदस्य को परिभाषित करने का सबसे सार रूप है। चूंकि लक्षण आमतौर पर अमूर्त इंटरफेस होते हैं, इसलिए आप चाहते हैं कि एक val
कह रहा है कि कार्यान्वयन कैसे करना चाहिए। यदि आप एक के लिए पूछते हैं val
, तो एक कार्यान्वयन वर्ग ए का उपयोग नहीं कर सकता है def
।
ए val
की आवश्यकता केवल तभी होती है जब आपको एक स्थिर पहचानकर्ता की आवश्यकता होती है, उदाहरण के लिए पथ-निर्भर प्रकार। यह ऐसी चीज है जिसकी आपको आमतौर पर जरूरत नहीं होती है।
की तुलना करें:
trait Foo { def bar: Int }
object F1 extends Foo { def bar = util.Random.nextInt(33) }
class F2(val bar: Int) extends Foo // ok
object F3 extends Foo {
lazy val bar = {
Thread.sleep(5000)
42
}
}
अगर आप के पास था
trait Foo { val bar: Int }
आप परिभाषित F1
या नहीं कर पाएंगे F3
।
ठीक है, और आपको भ्रमित करने के लिए और उत्तर देने में @ om-nom-nom- अमूर्त val
s का उपयोग करने से प्रारंभिक समस्याएं हो सकती हैं:
trait Foo {
val bar: Int
val schoko = bar + bar
}
object Fail extends Foo {
val bar = 33
}
Fail.schoko
यह एक बदसूरत समस्या है जिसे मेरी निजी राय को संकलक में तय करके भविष्य के स्काला संस्करणों में दूर जाना चाहिए, लेकिन हां, वर्तमान में यह भी एक कारण है कि किसी को अमूर्त val
एस का उपयोग नहीं करना चाहिए ।
संपादित करें (जनवरी 2016): आपको val
एक lazy val
कार्यान्वयन के साथ एक सार घोषणा को ओवरराइड करने की अनुमति है , ताकि प्रारंभिक विफलता को भी रोका जा सके।