আপডেট 2016/02/25:
যদিও আমি নীচে লিখেছি উত্তর যথেষ্ট ছিল, কেস ক্লাসের সহযোগী অবজেক্ট সম্পর্কিত এটি সম্পর্কিত আরও একটি জবাব উল্লেখ করাও মূল্যবান। যথা, কেউ কীভাবে সংকলক উত্পাদিত অন্তর্নিহিত সহকর্মী অবজেক্টটি পুনরুত্পাদন করে যখন ঘটে কেবল যখন কেস ক্লাসটি নিজেই সংজ্ঞায়িত করা হয়। আমার জন্য, এটি পাল্টা স্বজ্ঞাত হয়ে উঠেছে।
সংক্ষিপ্তসার:
কেস ক্লাসের প্যারামিটারের মান কেস ক্লাসে সংরক্ষণ করার আগে আপনি এটি কেবলমাত্র বৈধ (আটেড) এডিটি (অ্যাবস্ট্রাক্ট ডেটা টাইপ) বাকী থাকাতে পরিবর্তন করতে পারেন। যদিও সমাধানটি তুলনামূলকভাবে সহজ ছিল, বিশদটি আবিষ্কার করা কিছুটা চ্যালেঞ্জিং ছিল।
বিশদ:
আপনি যদি কেবলমাত্র আপনার কেস শ্রেণির বৈধ উদাহরণগুলি নিশ্চিত করতে চান যা কোনও এডিটি (অ্যাবস্ট্রাক্ট ডেটা টাইপ) এর পিছনে একটি অত্যাবশ্যক অনুমান, তবে আপনাকে অবশ্যই অনেক কিছু করতে হবে।
উদাহরণস্বরূপ, একটি সংকলক উত্পন্ন copy
পদ্ধতি কেস ক্লাসে ডিফল্টরূপে সরবরাহ করা হয়। সুতরাং, আপনি যদি নিশ্চিত হয়েছিলেন যে কেবলমাত্র স্পষ্টত সহযোগী অবজেক্টের apply
পদ্ধতির মাধ্যমেই কেবলমাত্র উদাহরণ তৈরি করা হয়েছিল যা গ্যারান্টিযুক্ত যে তারা কেবল উচ্চতর ক্ষেত্রে মানগুলি ধারণ করতে পারে তবে নিম্নলিখিত কোডটি একটি নিম্ন কেস মান সহ কেস শ্রেণীর উদাহরণ তৈরি করবে:
val a1 = A("Hi There")
val a2 = a1.copy(s = "gotcha")
অতিরিক্তভাবে, কেস ক্লাসগুলি প্রয়োগ করে java.io.Serializable
। এর অর্থ হল যে আপনার সাবধানতার কৌশলটি কেবল উচ্চতর ক্ষেত্রে যেমন একটি সাধারণ পাঠ্য সম্পাদক এবং deserialization দ্বারা বিভক্ত করা যেতে পারে।
সুতরাং, আপনার কেস ক্লাসটি বিভিন্ন উপায়ে ব্যবহার করা যেতে পারে (উদারতা এবং / বা খারাপভাবে), আপনার অবশ্যই করা কর্মগুলি এখানে:
- আপনার সুস্পষ্ট সহচর বস্তুর জন্য:
- আপনার কেস ক্লাসের মতো একই নাম ব্যবহার করে এটি তৈরি করুন
- এটি কেস ক্লাসের ব্যক্তিগত অংশগুলিতে অ্যাক্সেস করতে পারে
apply
আপনার কেস শ্রেণির জন্য প্রাথমিক নির্মাতার মতো ঠিক একই স্বাক্ষর সহ একটি পদ্ধতি
তৈরি করুন
- ২.১ ধাপ শেষ হয়ে গেলে এটি সফলভাবে সংকলন করবে
new
অপারেটরটি ব্যবহার করে কেস ক্লাসের উদাহরণ গ্রহণ করে একটি ফাঁকা বাস্তবায়ন সরবরাহ করুন implementation{}
- এটি এখন আপনার শর্তাদির উপর কঠোরভাবে কেস ক্লাস ইনস্ট্যান্ট করবে
- খালি বাস্তবায়ন
{}
অবশ্যই সরবরাহ করতে হবে কারণ কেস ক্লাস ঘোষিত হয়েছে abstract
(২.১ পদক্ষেপ দেখুন)
- আপনার কেস ক্লাসের জন্য:
- এটি ঘোষণা করুন
abstract
apply
সঙ্গী অবজেক্টে এমন কোনও পদ্ধতি তৈরি করা থেকে স্কালার সংকলককে বাধা দেয় যা "পদ্ধতির দ্বিগুণ সংজ্ঞায়িত ..." সংকলনের ত্রুটির কারণ ঘটায় (উপরে 1.2 ধাপ)
- প্রাথমিক কনস্ট্রাক্টর হিসাবে চিহ্নিত করুন
private[A]
- প্রাথমিক নির্মাতা এখন কেবল কেস ক্লাসে এবং তার সহযোগী অবজেক্টের জন্য উপলব্ধ (যেটি আমরা উপরে ১.১ পদে সংজ্ঞায়িত করেছি)
- একটি
readResolve
পদ্ধতি
তৈরি করুন
- প্রয়োগ পদ্ধতি ব্যবহার করে একটি বাস্তবায়ন সরবরাহ করুন (উপরে 1.2 ধাপ)
- একটি
copy
পদ্ধতি
তৈরি করুন
- কেস ক্লাসের প্রাথমিক নির্মাণকারীর মতো ঠিক একই স্বাক্ষর রাখতে এটি সংজ্ঞায়িত করুন
- প্রতিটি প্যারামিটারের জন্য একই প্যারামিটারের নামটি ব্যবহার করে একটি ডিফল্ট মান যুক্ত করুন (উদাঃ
s: String = s
)
- প্রয়োগ পদ্ধতি ব্যবহার করে একটি বাস্তবায়ন সরবরাহ করুন (নীচে 1.2 ধাপ)
উপরের ক্রিয়া সহ আপনার কোডটি এখানে পরিবর্তন করা হয়েছে:
object A {
def apply(s: String, i: Int): A =
new A(s.toUpperCase, i) {}
}
abstract case class A private[A] (s: String, i: Int) {
private def readResolve(): Object =
A.apply(s, i)
def copy(s: String = s, i: Int = i): A =
A.apply(s, i)
}
এবং প্রয়োজনীয়গুলি প্রয়োগ করার পরে আপনার কোডটি এখানে রয়েছে (@ollekullberg উত্তরে প্রস্তাবিত) এবং কোনও ধরণের ক্যাশে রাখার জন্য আদর্শ জায়গাটি সনাক্তকরণ:
object A {
def apply(s: String, i: Int): A = {
require(s.forall(_.isUpper), s"Bad String: $s")
new A(s, i) {}
}
}
abstract case class A private[A] (s: String, i: Int) {
private def readResolve(): Object =
A.apply(s, i)
def copy(s: String = s, i: Int = i): A =
A.apply(s, i)
}
এবং এই সংস্করণটি আরও সুরক্ষিত / শক্তিশালী যদি এই কোডটি জাভা ইন্টারপের মাধ্যমে ব্যবহার করা হয় (কেস ক্লাসটি প্রয়োগ হিসাবে লুকিয়ে রাখে এবং একটি চূড়ান্ত শ্রেণি তৈরি করে যা ডেরাইভেশনগুলি আটকায়):
object A {
private[A] abstract case class AImpl private[A] (s: String, i: Int)
def apply(s: String, i: Int): A = {
require(s.forall(_.isUpper), s"Bad String: $s")
new A(s, i)
}
}
final class A private[A] (s: String, i: Int) extends A.AImpl(s, i) {
private def readResolve(): Object =
A.apply(s, i)
def copy(s: String = s, i: Int = i): A =
A.apply(s, i)
}
যদিও এটি সরাসরি আপনার প্রশ্নের উত্তর দেয়, উদাহরণস্বরূপ ক্যাচিংয়ের বাইরে কেস ক্লাসের চারপাশে এই পথটি প্রসারিত করার আরও অনেক উপায় রয়েছে। আমার নিজের প্রকল্পের চাহিদা জন্য, আমি আছে একটি এমনকি আরো বিস্তৃত সমাধান নির্মিত যা আমি করেছি CodeReview নথিভুক্ত (ক Stackoverflow বোন সাইট)। আপনি যদি আমার সমাধানটি ব্যবহার করে বা কাজে লাগিয়ে শেষ করেন, দয়া করে আমাকে প্রতিক্রিয়া, পরামর্শ বা প্রশ্ন রেখে বিবেচনা করুন এবং কারণ হিসাবে, আমি এক দিনের মধ্যে সাড়া দেওয়ার জন্য যথাসাধ্য চেষ্টা করব।