কেস ক্লাস উদাহরণ ক্লোন করতে এবং স্কালায় কেবল একটি ক্ষেত্র পরিবর্তন করতে?


208

ধরা যাক আমার একটি কেস ক্লাস রয়েছে যা বিভিন্ন সামাজিক নেটওয়ার্কের ব্যক্তিত্ব, ব্যক্তির প্রতিনিধিত্ব করে। এই শ্রেণীর উদাহরণগুলি সম্পূর্ণরূপে অপরিবর্তনীয়, এবং অব্যাহত সংগ্রহগুলিতে অনুষ্ঠিত হয়, অবশেষে একজন আক্কা অভিনেতা দ্বারা সংশোধন করা।

এখন, আমার অনেকগুলি ক্ষেত্রের সাথে কেস ক্লাস রয়েছে এবং আমি একটি বার্তা পেয়েছি যা বলছে আমাকে অবশ্যই একটি ক্ষেত্র আপডেট করতে হবে, এরকম কিছু:

case class Persona(serviceName  : String,
                   serviceId    : String,
                   sentMessages : Set[String])

// Somewhere deep in an actor
val newPersona = Persona(existingPersona.serviceName,
                         existingPersona.serviceId,
                         existingPersona.sentMessages + newMessage)

লক্ষ্য করুন আমাকে সমস্ত ক্ষেত্র নির্দিষ্ট করতে হবে, যদিও কেবলমাত্র একটি পরিবর্তন রয়েছে। যে সমস্ত ক্ষেত্র পরিবর্তন হয় না তা নির্দিষ্ট করে না করে কি বিদ্যমান পার্সোনাকে ক্লোন করার এবং শুধুমাত্র একটি ক্ষেত্র প্রতিস্থাপন করার কোনও উপায় আছে? আমি কি এটি বৈশিষ্ট্য হিসাবে লিখতে এবং এটি আমার সমস্ত কেস ক্লাসের জন্য ব্যবহার করতে পারি?

পার্সোনা যদি মানচিত্রের মতো উদাহরণ হয় তবে এটি করা সহজ।

উত্তর:


324

case classএমন একটি copyপদ্ধতি নিয়ে আসে যা এই ব্যবহারের জন্য উত্সর্গীকৃত:

val newPersona = existingPersona.copy(sentMessages = 
                   existingPersona.sentMessages + newMessage)

5
সেই নথিটি কোথায়? আমি "সুস্পষ্ট" দাগ, কপি একটি রেফারেন্স খুঁজে পাচ্ছি না scala-lang.org/api/current/index.html উদাহরণস্বরূপ।
ফ্রান্সোইস বিউসোলিল

6
এটি ভাষার বৈশিষ্ট্য, আপনি এটি স্ক্যালাল স্পেসিফিকেশনটিতে দেখতে পাবেন: scala-lang.org/docu/files/ScalaReferences.pdf §5.3.2। এটি এপিআইতে নেই কারণ এটি এপিআইয়ের অংশ নয়;)
নিকোলাস

1
আমি স্কেলডোকের অনুলিপি করার পদ্ধতিগুলি যখন উপস্থিত রয়েছে তখনই তা তৈরি করার ইচ্ছা নিয়েছিলাম, আপনি কি চান না?
Soc

4
এটা ভাল হবে। তবে এখানে, ফ্রেঞ্চোইসের সমস্যা (যদি আমি ঠিক থাকি) তবে তিনি জানতেন না যে তিনি কোনও copyঘোষণা দিলে তার কোনও পদ্ধতি থাকবে case class
নিকোলাস

2
@ জোনাথননিউফেল্ড আপনি সেই সংবেদন দিয়ে খাঁটি এফপি শিবিরে অনেক বন্ধু বান্ধব করবেন। আমি আপনার সাথে সহমত করছি।
জাভদ্বা

46

২.৮ সাল থেকে, স্কালা কেস ক্লাসগুলির একটি copyপদ্ধতি রয়েছে যা এর যাদুতে কাজ করার জন্য নামযুক্ত / ডিফল্ট প্যারামগুলির সুবিধা গ্রহণ করে:

val newPersona =
  existingPersona.copy(sentMessages = existing.sentMessages + newMessage)

আপনি ব্যবহারকে Personaসহজ করার জন্য একটি পদ্ধতিও তৈরি করতে পারেন :

case class Persona(
  svcName  : String,
  svcId    : String,
  sentMsgs : Set[String]
) {
  def plusMsg(msg: String) = this.copy(sentMsgs = this.sentMsgs + msg)
}

তারপর

val newPersona = existingPersona plusMsg newMsg


0

ব্যবহার করার কথা বিবেচনা lensমধ্যে Shapelessগ্রন্থাগার:

import shapeless.lens

case class Persona(serviceName  : String,
                   serviceId    : String,
                   sentMessages : Set[String])
// define the lens
val messageLens = lens[Persona] >> 'sentMessages 

val existingPersona = Persona("store", "apple", Set("iPhone"))

// When you need the new copy, by setting the value,
val newPersona1 = messageLens.set(existingPersona)(Set.empty)
// or by other operation based on current value.
val newPersona2 = messageLens.modify(existingPersona)(_ + "iPad")

// Results:
// newPersona1: Persona(store,apple,Set())
// newPersona2: Persona(store,apple,Set(iPhone, iPad))

তদতিরিক্ত, যদি আপনি কেস ক্লাস নেস্ট করে থাকেন তবে রচনাগুলিgetter এবং setterপদ্ধতিগুলি রচনা করা কিছুটা ক্লান্তিকর হতে পারে। লেন্স লাইব্রেরি ব্যবহার করে সরল করার ভাল সুযোগ হবে be

দয়া করে দেখুন:


0

আমি জটিল লেন্সগুলি করতে কোনও বড় লাইব্রেরি অন্তর্ভুক্ত করতে চাইনি যা আপনাকে নেস্টেড কেস ক্লাসে মানগুলি গভীর করে দেয়। দেখা যাচ্ছে এটি স্কালাজ লাইব্রেরিতে কোডের কয়েকটি লাইনই রয়েছে :

  /** http://stackoverflow.com/a/5597750/329496 */
  case class Lens[A, B](get: A => B, set: (A, B) => A) extends ((A) => B) with Immutable {
    def apply(whole: A): B = get(whole)

    def mod(a: A, f: B => B) = set(a, f(this (a)))

    def compose[C](that: Lens[C, A]) = Lens[C, B](
      c => this(that(c)),
      (c, b) => that.mod(c, set(_, b))
    )

    def andThen[C](that: Lens[B, C]) = that compose this
  }

তারপরে আপনি বিল্ট ইন অনুলিপি বৈশিষ্ট্যটি ব্যবহারের চেয়ে গভীরতর নেস্টেড মানগুলি সেট করে এমন লেন্স তৈরি করতে পারেন। জটিল গ্রন্থাগারগুলি যদি আমার লাইব্রেরিটি ভারী নেস্টেড মানগুলি সেট করতে ব্যবহার করে তবে একটি বড় সংস্থার লিঙ্কটি এখানে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.