स्काला में "नया" कीवर्ड


93

मेरा एक बहुत ही सरल प्रश्न है - स्काला में ऑब्जेक्ट बनाते समय हमें नया कीवर्ड कब लागू करना चाहिए? क्या यह तब होता है जब हम जावा वस्तुओं को केवल इंस्टेंट करने की कोशिश करते हैं?

जवाबों:


144

newजब आप किसी classस्वयं के निर्माता को संदर्भित करना चाहते हैं , तो कीवर्ड का उपयोग करें :

class Foo { }

val f = new Foo

newयदि आप साथी वस्तु applyविधि की बात कर रहे हैं तो छोड़ें :

class Foo { }
object Foo {
    def apply() = new Foo
}

// Both of these are legal
val f = Foo()
val f2 = new Foo

यदि आपने एक केस क्लास बनाया है:

case class Foo()

स्काला चुपके से आपके लिए एक साथी वस्तु बनाता है, इसे इस में बदल देता है:

class Foo { }
object Foo {
    def apply() = new Foo
}

तो आप कर सकते हैं

f = Foo()

अंत में, ध्यान रखें कि ऐसा कोई नियम नहीं है जो कहता है कि साथी apply विधि को निर्माता के लिए एक प्रॉक्सी होना चाहिए:

class Foo { }
object Foo {
    def apply() = 7
}

// These do different things
> println(new Foo)
test@5c79cc94
> println(Foo())
7

और, चूंकि आपने जावा कक्षाओं का उल्लेख किया है: हां - जावा कक्षाओं में शायद ही कभी एक applyविधि के साथ साथी ऑब्जेक्ट होते हैं , इसलिए आपको उपयोग करना होगा newऔर वास्तविक वर्ग का निर्माता।


1
एक जावा क्लास में कभी भी साथी ऑब्जेक्ट नहीं हो सकता है। इसमें एक ऑब्जेक्ट हो सकता है जो जावा वर्ग के लिए एक कारखाने के रूप में काम कर सकता है - लेकिन यह ऑब्जेक्ट इसका साथी ऑब्जेक्ट नहीं है।
किर्त्सु 20

@Antoras चूंकि स्काला कक्षाएं जावा बाइटकोड के लिए संकलित होती हैं, और संकलित रूप में वितरित की जा सकती हैं, क्या स्काला एक वास्तविक स्काला साथी और एक स्थिर MODULE $ सदस्य के साथ फू $ नामक वर्ग के बीच अंतर बता सकती है?
ओवेन

1
मुझे लगता है कि स्केलक इसे अलग कर सकता है क्योंकि यह अनुमान लगाया जाता है कि एक साथी ऑब्जेक्ट को उसी फ़ाइल में घोषित किया जाना है जो उसके साथी वर्ग के रूप में है। क्योंकि साथी "संपत्ति" केवल स्काला में मौजूद है न कि बायटेकोड स्तर के स्कैलेक पर, स्कैला कोड की जांच करने के लिए और न कि बायटेकोड पर यह सुनिश्चित करने के लिए कि कल्पना का पालन किया जाता है।
किरित्सुकु

1
जावा कक्षाओं का कोई भी उदाहरण जो स्काला में नए कीवर्ड का उपयोग नहीं करता है?
Bober02

साथ ही साथी ऑब्जेक्ट पर विधियों को कक्षा पर स्थिर तरीकों के माध्यम से भी सुलभ बनाया जाएगा और यह जावा वर्गों के साथ कभी नहीं होगा जिसके लिए आप बाद में "साथी" को परिभाषित करते हैं।
drexin

16

क्या यह तब होता है जब हम जावा ऑब्जेक्ट को केवल इंस्टेंट करने की कोशिश करते हैं?

हर्गिज नहीं। दो सामान्य मामले हैं जब आप स्कैला newमें ओम्मिट करते हैं । सिंगलटन ऑब्जेक्ट्स के साथ (जिसका उपयोग अक्सर स्थिर कार्यों को स्टोर करने के लिए किया जाता है और जैसा कि आप जावा में देख सकते हैं, उसी तरह के कारखाने के रूप में किया जाता है):

scala> object LonelyGuy { def mood = "sad" }
defined module LonelyGuy

scala> LonelyGuy
res0: LonelyGuy.type = LonelyGuy$@3449a8

scala> LonelyGuy.mood
res4: java.lang.String = sad

एक साथ मामले वर्गों (वास्तव में, खाने के नीचे वर्ग + ऑब्जेक्ट = हैं साथी पैटर्न, जैसे होने वर्ग और वस्तु ही नाम के साथ):

scala> case class Foo(bar: String) 
defined class Foo


scala> Foo("baz")
res2: Foo = Foo(baz)

इसलिए जब आप एक साधारण वर्ग के साथ काम करते हैं, तो नियम जावा के साथ समान होते हैं।

scala> class Foo(val bar: String) 
defined class Foo

scala> new Foo("baz")
res0: Foo = Foo@2ad6a0

// will be a error 
scala> Foo("baz")
<console>:8: error: not found: value Foo
       Foo("baz")

बोनस, स्काला में एक अनाम वर्ग है, जिसका निर्माण इस तरह किया जा सकता है:

scala> new { val bar = "baz" }
res2: java.lang.Object{val bar: java.lang.String} = $anon$1@10ee5b8

scala> res2.bar
res3: java.lang.String = baz

1
तुम ठीक है कली?
याकूब बी

0

क्या यह तब होता है जब हम जावा वस्तुओं को केवल इंस्टेंट करने की कोशिश करते हैं?

स्काला 3 के साथ (जो कि 2020 के मध्य में जारी किया जाना चाहिए, आठ साल बाद), डॉट्टी के आधार पर : कभी नहीं।

स्कैला 3 " new" गिरा देगा , जैसा कि इस धागे में है

निर्माता अनुप्रयोग एक वर्ग के उदाहरणों को बनाने के लिए सरल फ़ंक्शन कॉल सिंटैक्स का उपयोग करने की अनुमति देते हैं, भले ही कोई लागू विधि लागू न हो।

उदाहरण:

class StringBuilder(s: String) {
   def this() = this(s)
}

StringBuilder("abc")  // same as new StringBuilder("abc")
StringBuilder()       // same as new StringBuilder()

निर्माता एप्लिकेशन केवल केस कक्षाओं के लिए प्रदान की गई कार्यक्षमता को सामान्य करते हैं, लेकिन यह कैसे प्राप्त होता है इसका तंत्र थोड़ा अलग है।
ऑटो-जनरेटेड अप्लाई विधि के बजाय, हम एक फंक्शन कॉल में एक नई संभावित व्याख्या जोड़ते हैं f(args)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.