एक मौजूदा JVM में क्रम वस्तु ढेर पर एक निश्चित आकार है। इसमें एक विशेषता जोड़ने से ढेर पर इसका आकार बदलना होगा, और इसके हस्ताक्षर बदलना होगा।
तो जाने का एकमात्र तरीका संकलन समय पर किसी प्रकार का परिवर्तन करना होगा।
स्कैला में मिक्सिन संरचना संकलन समय पर होती है। संभावित कंपाइलर संभावित रूप से क्या कर सकता है एक मौजूदा ऑब्जेक्ट ए के आस-पास एक रैपर बी बना सकता है, उसी प्रकार के साथ जो केवल मौजूदा ऑब्जेक्ट ए को सभी कॉल अग्रेषित करता है, और फिर एक विशेषता टी से बी में मिलाता है। हालांकि, यह लागू नहीं किया गया है। जब यह संभव होगा, यह संदिग्ध है, क्योंकि ऑब्जेक्ट ए अंतिम श्रेणी का उदाहरण हो सकता है, जिसे विस्तारित नहीं किया जा सकता है।
संक्षेप में, मौजूदा ऑब्जेक्ट उदाहरणों पर मिश्रित संरचना संभव नहीं है।
UPDATED:
स्मार्ट समाधान गोगोल शान द्वारा प्रस्तावित करने के लिए संबंधित, और किसी भी लक्षण के साथ काम करने के लिए इसे सामान्यीकरण, यह जहाँ तक मुझे मिल गया है। विचार DynamicMixinCompanion
विशेषता में सामान्य मिश्रित कार्यक्षमता निकालने के लिए है। क्लाइंट को प्रत्येक गुण के लिए DynamicMixinCompanion
का विस्तार करने वाला एक साथी ऑब्जेक्ट बनाना चाहिए, जिसके लिए वह गतिशील मिश्रण कार्यक्षमता चाहता है। इस साथी ऑब्जेक्ट को अज्ञात विशेषता वस्तु को परिभाषित करने की आवश्यकता है (::
)।
val o = DBHelper.loadMyEntityFromDB(primaryKey) :: MyTrait
o.doSomething
मैं: अपने उदाहरण कोड के लिए
import MyTrait._
val a = new Test
val b = a :: MyTrait
b.doSomething
b.f
:
//if I had a class like this
final class Test {
def f = println("foo")
}
trait MyTrait {
def doSomething = {
println("boo")
}
}
object MyTrait {
implicit def innerObj(o:MixTest) = o.obj
def ::(o:Test) = new MixTest(o)
final class MixTest private[MyTrait](val obj:Test) extends MyTrait
}
आप नीचे के रूप में इस विशेषता का उपयोग कर सकते हैं:
trait DynamicMixinCompanion[TT] {
implicit def baseObject[OT](o: Mixin[OT]): OT = o.obj
def ::[OT](o: OT): Mixin[OT] with TT
class Mixin[OT] protected[DynamicMixinCompanion](val obj: OT)
}
trait OtherTrait {
def traitOperation = println("any trait")
}
object OtherTrait extends DynamicMixinCompanion[OtherTrait] {
def ::[T](o: T) = new Mixin(o) with OtherTrait
}
object Main {
def main(args: Array[String]) {
val a = "some string"
val m = a :: OtherTrait
m.traitOperation
println(m.length)
}
}
यह एक बहुत ही उपयोगी भ्रूण है, जब आपने 'निहित' के साथ एक विधि परिभाषित की है, और इस विधि को अपने दायरे में आयात किया है, तो यह विधि विधि ऑब्जेक्ट को निर्दिष्ट करने में आपकी मदद कर सकती है जो विधि तर्क द्वारा निर्दिष्ट किसी अन्य ऑब्जेक्ट को निर्दिष्ट करती है बाद की विधि को आह्वान करने की आवश्यकता है जिसे पूर्व में परिभाषित नहीं किया गया है। –
बहुत अच्छा समाधान, मुझे यह पसंद है। मुझे आश्चर्य है कि इसे सामान्य रूप से कितना आसानी से बनाया जा सकता है - शायद 'मायट्रेट' ऑब्जेक्ट में '::' के लिए एक सामान्य पैरामीटर जोड़ें, इसे किसी भी प्रकार के लिए काम करने की अनुमति दे सकता है। क्या इसे मनमाना लक्षणों के साथ काम करने के लिए भी बनाया जा सकता है जिसे हम मिश्रण करना चाहते हैं ...? – axel22
@ axel22 हाँ, मुझे लगता है कि इसे मेरे अद्यतन उत्तर की तरह सामान्य बनाया जा सकता है। लेकिन मैं इसे मनमाना विशेषता के साथ काम करने के लिए नहीं बनाया जा सकता, मैं स्कैला के लिए नौसिखिया हूँ। –