আমি reifiedকীওয়ার্ডের উদ্দেশ্যটি বোঝার চেষ্টা করছি , স্পষ্টতই এটি আমাদের জেনেরিকের প্রতিচ্ছবি করতে দেয় ।
যাইহোক, আমি এটি ছেড়ে দিলে এটি ঠিক ঠিক কাজ করে। কেউ যখন বোঝাতে আগ্রহী এটি কখন একটি বাস্তব পার্থক্য করে ?
আমি reifiedকীওয়ার্ডের উদ্দেশ্যটি বোঝার চেষ্টা করছি , স্পষ্টতই এটি আমাদের জেনেরিকের প্রতিচ্ছবি করতে দেয় ।
যাইহোক, আমি এটি ছেড়ে দিলে এটি ঠিক ঠিক কাজ করে। কেউ যখন বোঝাতে আগ্রহী এটি কখন একটি বাস্তব পার্থক্য করে ?
উত্তর:
reifiedভালfun <T> myGenericFun(c: Class<T>)
জেনেরিক ফাংশনের মতো myGenericFun, আপনি টাইপটি অ্যাক্সেস করতে পারবেন না Tকারণ এটি কেবলমাত্র সংকলন সময়ে পাওয়া যায় তবে রানটাইমে মুছে ফেলা হয়। অতএব, আপনি যদি ফাংশন বডিটিতে জেনেরিক টাইপটিকে একটি সাধারণ শ্রেণি হিসাবে ব্যবহার করতে চান তবে আপনাকে স্পষ্টভাবে ক্লাসটি প্যারামিটার হিসাবে যেমন প্রদর্শিত হবে তেমনভাবে পাস করতে হবে myGenericFun।
আপনি যদি inlineকোনও রিফাইড দিয়ে কোনও ফাংশন তৈরি করেন তবে রানটাইমের সময়ও এ Tধরণের Tঅ্যাক্সেস পাওয়া যায় এবং সুতরাং আপনাকে Class<T>অতিরিক্তভাবে পাস করার দরকার নেই । আপনার সাথে কাজ করতে Tযেমন যদি এটা একটি স্বাভাবিক বর্গ ছিল, যেমন আপনি একটি পরিবর্তনশীল একটি কিনা চেক করতে চান পারে দৃষ্টান্ত T , যা আপনি সহজে তারপর করতে পারেন: myVar is T।
টাইপ inlineসহ এই জাতীয় ফাংশন নীচে দেখায়:reifiedT
inline fun <reified T> myGenericFun()
reifiedকাজ করেআপনি কেবল reifiedকোনও inlineফাংশনের সংমিশ্রণে ব্যবহার করতে পারেন । এই জাতীয় ফাংশন কম্পাইলার যেখানে ফাংশনটি ব্যবহৃত হচ্ছে সেখানে ফাংশনের বাইকোড অনুলিপি করে (ফাংশনটি "ইনলাইনড" হচ্ছে)। আপনি যখন সংশোধিত প্রকারের সাথে একটি ইনলাইন ফাংশনটি কল করবেন তখন সংকলকটি টাইপ আর্গুমেন্ট হিসাবে ব্যবহৃত প্রকৃত প্রকারটি জানে এবং সরাসরি সংশ্লিষ্ট বর্গটি ব্যবহার করতে উত্পন্ন বাইকোডকে সংশোধন করে। সুতরাং বাইটকোডে এবং রানটাইমে কল myVar is Tহয়ে ওঠার মতো কল myVar is String(যদি প্রকারের যুক্তিটি ছিল String)।
আসুন একটি উদাহরণ দেখুন যা দেখায় যে কতটা সহায়ক reifiedহতে পারে। আমরা Stringযার জন্য একটি এক্সটেনশন ফাংশন তৈরি করতে চাই toKotlinObjectযা ফাংশনের জেনেরিক ধরণ দ্বারা নির্দিষ্ট একটি প্রকারের সাথে একটি JSON স্ট্রিংকে একটি সরল কোটলিন অবজেক্টে রূপান্তরিত করার চেষ্টা করে T। আমরা এটির com.fasterxml.jackson.module.kotlinজন্য ব্যবহার করতে পারি এবং প্রথম পদ্ধতিটি নিম্নলিখিত:
ক) সংশোধিত প্রকার ছাড়াই প্রথম পন্থা
fun <T> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
//does not compile!
return mapper.readValue(this, T::class.java)
}
readValueপদ্ধতি একটি টাইপ এটি বিশ্লেষণ করতে অনুমিত এর লাগে JsonObjectকরতে। যদি আমরা Classটাইপ প্যারামিটারটি পেতে চেষ্টা করি T, সংকলকটি অভিযোগ করে: "'টি' রিফাইড টাইপ প্যারামিটার হিসাবে ব্যবহার করতে পারবেন না instead পরিবর্তে একটি শ্রেণি ব্যবহার করুন" "
খ) সুস্পষ্ট Classপ্যারামিটারের সাথে কাজ করা
fun <T: Any> String.toKotlinObject(c: KClass<T>): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, c.java)
}
একটি ওয়ার্কঅ্যারাউন্ড হিসেবে Classএর Tএকটি পদ্ধতি প্যারামিটার, যা একটি যুক্তি হিসেবে ব্যবহার করা যেতে পারে readValue। এটি কাজ করে এবং জেনেরিক জাভা কোডের একটি সাধারণ প্যাটার্ন। এটি নিম্নলিখিত হিসাবে বলা যেতে পারে:
data class MyJsonType(val name: String)
val json = """{"name":"example"}"""
json.toKotlinObject(MyJsonType::class)
গ) কোটলিন পথ: reified
টাইপ প্যারামিটার inlineসহ একটি ফাংশন ব্যবহার করে ফাংশনটিকে ভিন্নভাবে প্রয়োগ করা সম্ভব করে তোলে:reifiedT
inline fun <reified T: Any> String.toKotlinObject(): T {
val mapper = jacksonObjectMapper()
return mapper.readValue(this, T::class.java)
}
গ্রহণ করার কোন প্রয়োজন নেই Classএর Tঅতিরিক্ত হিসাবে, Tব্যবহার করা যেতে পারে যেমন যদি এটা একজন সাধারণ বর্গ ছিল। ক্লায়েন্টের জন্য কোডটি দেখতে এরকম দেখাচ্ছে:
json.toKotlinObject<MyJsonType>()
সহ একটি inlined ফাংশন reifiedধরনের জাভা থেকে callable না কোড।
সহজ
* সংশোধনকালে সংশোধন করার সময় ব্যবহারের অনুমতি দেওয়ার জন্য রিফাইড করা হয়েছে (ডি ফাংশনের ভিতরে টি অ্যাক্সেস করতে)
উদাহরণ:
inline fun <reified T:Any> String.convertToObject(): T{
val gson = Gson()
return gson.fromJson(this,T::class.java)
}
মত ব্যবহার:
val jsonStringResponse = "{"name":"bruno" , "age":"14" , "world":"mars"}"
val userObject = jsonStringResponse.convertToObject<User>()
println(user.name)