मैंने खुद को त्रुटि-प्रवण कोड में भागते हुए पाया है; पैटर्न यह है:

final class StateVars(val x:Int, val y:Int)

final class StateVarsMutable(var x:Int, var y:Int) {
  // req. case classes & >1 element w/ same ordering
  // - can also do similar with shapeless
  // def snapshot():StateVars = StateVars.tupled( 
  //  StateVarsMutable.unapply(this).get )
  def snapshot() = new StateVars(x, y) // generic
}

उपरोक्त उदाहरण में StateVarsMutable एक अभिनेता के भीतर समाहित हो सकता है, लेकिन अभिनेता कभी-कभी StateVars के साथ अपने राज्य का एक स्नैपशॉट भेज सकता है। ऐसा लगता है कि kailuowang's henkan का उपयोग किया जा सकता है। रन-टाइम प्रदर्शन से समझौता किए बिना, क्या इस स्थिति के लिए कोई सर्वोत्तम या सामान्य दृष्टिकोण है?

0
user6296589 2 अगस्त 2018, 17:05
इस पर कुछ स्पष्टीकरण चाहिए। क्या अभिनेता को StateVars या StateVarsMutable का स्नैपशॉट मिलता है? और क्या रनटाइम प्रदर्शन 2 केस वर्गों के बीच परिवर्तित होने से प्रभावित होता है?
 – 
emran
2 अगस्त 2018, 22:08
इस चर्चा के लिए अभिनेता StateVars भेजता है; आंतरिक रूप से, यह StateVarsMutable को बनाए रखता है - लेकिन दोनों रूपांतरण उपयुक्त हैं, अर्थात, .toMutable और .toImmutable (.snapshot() ऊपर)। मैं प्रदर्शन का उल्लेख करता हूं क्योंकि मैंने संभावित समाधानों पर विचार किया है जो फ़ील्ड नामों के लिए स्ट्रिंग पेश करते हैं या जो अतिरिक्त प्रतियां पेश करते हैं, उदाहरण के लिए, tupled या HList के माध्यम से।
 – 
user6296589
3 अगस्त 2018, 16:22
शायद मुद्दा पूरी तरह से (गुमराह करने वाली) आंतरिक स्थिति का उपयोग करने की इच्छा है।
 – 
user6296589
3 अगस्त 2018, 16:57
एक अभिनेता के लिए राज्य को एक परिवर्तनीय चर में रखना आम बात है, लेकिन इससे बचा जा सकता है। आपके परिदृश्य के लिए, मैं परिवर्तनशील और अपरिवर्तनीय संस्करणों के बीच रूपांतरण को संभालने के लिए apply विधि के साथ केस क्लास (एस) के लिए एक साथी ऑब्जेक्ट बनाउंगा।
 – 
emran
3 अगस्त 2018, 19:42

1 उत्तर

सबसे बढ़िया उत्तर

अपरिवर्तनीय वर्गों की परिवर्तनशीलता

प्रश्न में वर्णित पैटर्न अनावश्यक है।

case class in scala उस समस्या का समाधान करता है जो प्रश्न निरंतर डेटा संरचना पैटर्न का उपयोग करके संबोधित करने का प्रयास कर रहा है।

"केस" को शामिल करने के लिए प्रश्न की कक्षा घोषणा को संशोधित करना:

final case class StateVars(x: Int, y: Int)

नए राज्य का प्रतिनिधित्व करने वाली नई वस्तुओं को वापस करके इस राज्य को "म्यूट" करना अब संभव है:

val initialState = StateVars(0,0)

//Increment x while keeping y the same
val incrementX : StateVars = initialState copy (x = initialState.x + 1)

//Increment y while keeping x the same
val incrementY : StateVars = initialState copy (y = initialState.y + 1)

यदि आपको लगातार "स्नैपशॉट" बनाए रखने की आवश्यकता है तो var का उपयोग करें:

var snapshot : StateVars = StateVars(0,0)

snapshot = snapshot copy (x = snapshot.x + 1, y = snapshot.y +1)

अभिनेताओं के भीतर

एक Actor लिखना संभव है जो मूल्यों को बदलने की अनुमति देने के लिए become कार्यक्षमता का उपयोग करके "स्नैपशॉट" बनाए रखता है:

object StateVarsRequest

class StateVarsActor(initialStateVars : StateVars) extends Actor {

  private def update(currentSnapshot: StateVars) : Receive = {
    case stateVars : StateVars => context become update(stateVars)
    case _ : StateVarsRequest  => sender ! currentSnapshot
  }

  override def receive : Receive = update(initialStateVars)
}

snapshot को एक अपरिवर्तनीय वर्ग के सूचक के रूप में माना जा सकता है। जब एक अनुरोधकर्ता को संदेश में स्नैपशॉट प्राप्त होता है, तो उन्हें परिवर्तनशील सूचक नहीं, बल्कि अपरिवर्तनीय डेटा प्राप्त होता है।

इसलिए यदि अनुरोधकर्ता द्वारा अपना डेटा प्राप्त करने के बाद स्नैपशॉट बदल जाता है तो अनुरोधकर्ता का डेटा नहीं बदलता है।

0
Ramón J Romero y Vigil 23 मई 2021, 14:48