2010-11-01 13 views
9

मैं इस उदाहरण के साथ http://scala.sygneca.com/code/remoteactors खेल रहा हूं यह जानने के लिए कि दूरस्थ अभिनेता स्कैला (2.8.0) में कैसे काम करते हैं। विशेष रूप से मैंने थोड़ा संशोधित किया कि अभिनेताओं द्वारा भेजे गए संदेशों को निम्नानुसार परिभाषित किया गया है:केस ऑब्जेक्ट्स serializable और केस क्लास क्यों नहीं हैं?

sealed trait Event extends Serializable 
case object Ping extends Event 
case object Pong extends Event 
case object Quit extends Event 

और सब कुछ अपेक्षित काम करता है। दुर्भाग्यवश यदि मैं घटनाओं को केस ऑब्जेक्ट्स के बजाए केस कक्षाओं के रूप में परिभाषित करता हूं:

sealed trait Event extends Serializable 
case class Ping extends Event 
case class Pong extends Event 
case class Quit extends Event 

मेरा उदाहरण काम करना बंद कर देता है। अधिक विस्तार से ऐसा लगता है कि मामले के मामले क्रमिक हैं, मामले कक्षाएं नहीं हैं। दरअसल जब मैं इस अंतिम संशोधन मैं निम्नलिखित अपवाद के साथ अपने उदाहरण चलाने का प्रयास:

[email protected]: caught java.io.NotSerializableException: scalachat.remote.Ping$ 
java.io.NotSerializableException: scalachat.remote.Ping$ 
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156) 
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326) 
    at scala.actors.remote.JavaSerializer.serialize(JavaSerializer.scala:46) 
    at scala.actors.remote.NetKernel.namedSend(NetKernel.scala:38) 
    at scala.actors.remote.NetKernel.forward(NetKernel.scala:71) 
    at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:182) 
    at scala.actors.remote.DelegateActor$$anonfun$act$1$$anonfun$apply$1.apply(Proxy.scala:123) 
    at scala.actors.ReactorTask.run(ReactorTask.scala:34) 
    at scala.actors.ReactorTask.compute(ReactorTask.scala:66) 
    at scala.concurrent.forkjoin.RecursiveAction.exec(RecursiveAction.java:147) 
    at scala.concurrent.forkjoin.ForkJoinTask.quietlyExec(ForkJoinTask.java:422) 
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.mainLoop(ForkJoinWorkerThread.java:340) 
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:325) 

वहाँ एक कारण है कि मामले वस्तुओं serializable और मामले कक्षाएं नहीं कर सकते हैं बनाया जा सकता है है? क्या मेरे उदाहरण केस कक्षाओं के साथ काम करने का कोई तरीका है?

संपादित करें: विक्टर द्वारा सुझाए गए अनुसार और हारून द्वारा पुष्टि की गई है कि मैं कक्षा के बजाय साथी वस्तु को संदेश के रूप में भेज रहा हूं।

public class scalachat.remote.Ping extends java.lang.Object implements scalachat.remote.Event,java.io.Serializable,scala.ScalaObject,scala.Product 

साथी वस्तु नहीं है: इसके अलावा javap यह स्पष्ट प्रतीत होता है कि, जबकि कक्षा serializable है साथ संकलित कोड का निरीक्षण

public final class scalachat.remote.Ping$ extends scala.runtime.AbstractFunction0 implements scala.ScalaObject 

अब सवाल है: मैं कैसे निर्दिष्ट कर सकते हैं कि मैं चाहता हूँ साथी वस्तु के बजाय वर्ग का उपयोग करें?

pong ! Ping() 

लेकिन कुछ भी नहीं बदला है: मैं भी जब मैं संदेश भेजने के रूप में की तरह हारून ने सुझाव दिया कोष्टक के एक खाली जोड़ी गयी। अंत में मैं भी मामले वर्ग

case class Ping(i: Int) extends Event 

करने के लिए एक नकली पैरामीटर जोड़ा के रूप में संदेश भेजने:

pong ! Ping(0) 

लेकिन अभी भी कोई अंतर का सामना कर के बिना। कोई उपाय?

+2

जहां तक ​​मुझे पता है, आपको 'सीरियलज़ेबल' इंटरफेस को स्पष्ट रूप से कार्यान्वित करने की आवश्यकता नहीं है, क्योंकि दोनों केस क्लास और केस ऑब्जेक्ट्स पहले से ही '@ serializable' का उपयोग कर रहे हैं (यह सिर्फ शर्करा हुआ है)। स्ट्रिप कोड देखने के लिए अपने कोड को 'स्केलैक -प्रिंट' के साथ संकलित करें - इससे आपको यह पता लगाने में मदद मिल सकती है कि समस्या क्या है। आरईपीएल में एक छोटे से परीक्षण से पता चलता है कि केस कक्षाएं [डी-] 2.8.0 के खिलाफ धारावाहिक हो सकती हैं। –

+0

http://gist.github.com/657953 –

+0

http://scala-programming-language.1934581.n4.nabble.com/deprecate-serializable-td3002109।एचटीएमएल –

उत्तर

14
@serializable case class Foo 

मुझे आश्चर्य भी हुआ कि केस ऑब्जेक्ट प्रति डिफ़ॉल्ट क्रमिक थे।

संपादित करें: अपवाद को पढ़ने के बाद ठीक से मुझे लगता है कि:

आप मामले वर्ग का एक उदाहरण के बजाय तार पर मामला वर्ग के जनरेट किया गया सहयोग वस्तु भेजने के लिए, कोशिश कर रहे हैं।

+9

केस क्लास डिफ़ॉल्ट रूप से serializable भी हैं। बीटीडब्ल्यू, उपरोक्त स्निपेट्स में वर्गों को 'सीरियलज़ेबल' से प्राप्त होता है, जो '@ serializable' एनोटेशन –

+7

का उपयोग करने के बराबर के अधिकांश मामलों में है, सामान्यतः,' @ serializable' का उपयोग करने की अनुशंसा नहीं की जाती है, और शायद इसे जल्द ही हटा दिया जाएगा: http://scala-programming-language.1934581.n4.nabble.com/deprecate-serializable-td3002109.html –

+0

क्षमा करें, लेकिन मुझे लगता है कि आप मेरे प्रश्न का जवाब नहीं दे रहे हैं। @serializable एनोटेशन और सीरियलज़ेबल इंटरफ़ेस को विस्तारित करना लगभग समान होना चाहिए (भले ही पहले व्यक्ति को स्पष्ट रूप से बहिष्कृत किया जा रहा हो) फिर भी मैंने @ सेरिअलाइज़ेबल एनोटेशन का उपयोग करने का प्रयास किया और मुझे उसी प्रभाव का अनुभव हुआ: केस ऑब्जेक्ट को क्रमबद्ध किया जा सकता है जबकि मामले कक्षाएं नहीं कर सकती हैं। दूसरे शब्दों में भी @ serializable केस क्लास पिंग लिखने के लिए मेरे उदाहरण में काम नहीं करता है। –

4

पैरामीटर के बिना केस क्लास व्यर्थ और बहिष्कृत हैं। और मुझे स्केल में Serializable नहीं मिला, बस serializable। यदि आप इन चीजों को ठीक करते हैं तो क्या यह काम करता है?

+2

मैं केस कक्षाओं का बिल्कुल उपयोग करना चाहता था क्योंकि मुझे उनके लिए कुछ पैरामीटर जोड़ने की आवश्यकता थी। Serializable इंटरफ़ेस वास्तव में java.io पैकेज में से एक है और @serializable एनोटेशन का उपयोग करता है और वही समस्या देता है जिसे मैंने अनुभव किया है। इसके अलावा, मुझे पता है कि @ serializable एनोटेशन को बहिष्कृत किया जा रहा है और यही कारण है कि मैं इसका उपयोग करने से परहेज कर रहा था। –

+0

@ मारियो मेरा मतलब है scala.serializable, जो इसे करने का अनुशंसित तरीका है। –

संबंधित मुद्दे