কোটলিনে জিসনের সাথে টাইপটোকেন + জেনেরিকগুলি কীভাবে ব্যবহার করবেন


108

আমি একটি কাস্টম ক্লাস (টার্নস) থেকে জেনেরিক ধরণের তালিকা পেতে অক্ষম:

val turnsType = TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson(pref.turns, turnsType)

এটি বলেছিল:

cannot access '<init>' it is 'public /*package*/' in 'TypeToken'

উত্তর:


235

এই ইনলাইন মজা তৈরি করুন:

inline fun <reified T> Gson.fromJson(json: String) = fromJson<T>(json, object: TypeToken<T>() {}.type)

এবং তারপরে আপনি এটিকে কল করতে পারেন:

val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)

পূর্ববর্তী বিকল্পগুলি:

বিকল্প 1:

val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)

আপনাকে লাগাতে হবে object :এবং নির্দিষ্ট টাইপটি লিখতে হবেfromJson<List<Turns>>


বিকল্প 2:

@ চিত্তাকর্ষক উল্লেখ হিসাবে এটি এই উপায়েও অর্জন করা যেতে পারে:

inline fun <reified T> genericType() = object: TypeToken<T>() {}.type

হিসাবে ব্যবহত:

val turnsType = genericType<List<Turns>>()

4
: আপনি একটি সাহায্যকারী পদ্ধতি কি এই যে, তোমার জন্য তৈরি করতে পারেনinline fun <reified T> genericType() = object: TypeToken<T>() {}.type
কিরিল Rakhman

1
বা এমনকি জসন থেকে নতুন ওভারলোড পেতে গসনকে প্রসারিত করে যা এটি করে। কোটলিন প্রসারিত করার জন্য ডিজাইন করা হয়েছে, সুতরাং এটি আরও ভাল করতে এবং টাইপটোকেনগুলি গোপন করতে গসনকে প্রসারিত করুন।
জয়সন মিনার্ড

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

সম্পাদনা প্রত্যাখ্যান করা হয়েছে, নীচে আমার উত্তরটি একটি সম্পূর্ণ সংস্করণের জন্য দেখুন যা সমস্ত উত্তর এবং মন্তব্যগুলিকে একটি সুসংগত উত্তরে সংযুক্ত করে। আপনি নিজের উত্তরটি গ্রহণ করেছেন তবে এটি সম্পূর্ণ হয়নি।
জেইসন মিনার্ড

কোটলিন সতর্কতা অপসারণ: ইনলাইন মজা <রিফাইড টি> জেনেরিক টাইপ (): টাইপ? = অবজেক্ট: টাইপ টোকেন <টি> () {}। টাইপ
হুয়ান মেন্ডেজ

28

এটি সমস্যার সমাধান করে:

val turnsType = object : TypeToken<List<Turns>>() {}.type
val turns = Gson().fromJson<List<Turns>>(pref.turns, turnsType)

প্রথম লাইনটি একটি অবজেক্ট এক্সপ্রেশন তৈরি করে যা থেকে নেমে আসে TypeTokenএবং তার পরে জাভা পায় Type। তারপরে Gson().fromJsonপদ্ধতিটি হয় ফাংশনের ফলাফলের জন্য নির্দিষ্ট ধরণের প্রয়োজন (যা TypeTokenতৈরির সাথে মিলিত হওয়া উচিত )। এই কাজের দুটি সংস্করণ যেমন উপরে বা:

val turns: List<Turns> = Gson().fromJson(pref.turns, turnsType)

এটি তৈরি করা সহজ করার জন্য TypeTokenআপনি কোনও সহায়ক ফাংশন তৈরি করতে পারেন, যা ইনলাইন হওয়া দরকার যাতে এটি রিফাইড টাইপ পরামিতি ব্যবহার করতে পারে :

inline fun <reified T> genericType() = object: TypeToken<T>() {}.type

যা এর পরে এই যে কোনও একটির জন্য ব্যবহার করা যেতে পারে:

val turnsType = genericType<List<Turns>>()
// or
val turnsType: List<Turns> = genericType()

এবং পুরো প্রক্রিয়াটি Gsonউদাহরণস্বরূপ কোনও এক্সটেনশন ফাংশনে আবৃত হতে পারে :

inline fun <reified T> Gson.fromJson(json: String) = this.fromJson<T>(json, object: TypeToken<T>() {}.type)

যাতে আপনি কেবল গসনকে কল করতে পারেন এবং একেবারেই চিন্তা করবেন না TypeToken:

val turns = Gson().fromJson<Turns>(pref.turns)
// or
val turns: Turns = Gson().fromJson(pref.turns)

এখানে কোটলিন অ্যাসাইনমেন্টের একপাশ থেকে অন্য দিক থেকে টাইপ ইনফারেন্স ব্যবহার করছে এবং পূর্ণ প্রকারের (ক্ষয় ছাড়াই) অতিক্রম করার জন্য একটি ইনলাইন ফাংশনটির জন্য জেনেরিকগুলি সংশোধন করছে এবং এটি নির্মাণের জন্য এবং জিসনে TypeTokenকল করার জন্য ব্যবহার করছে


1
হাই @ জাইসন, আমি অ্যান্ড্রয়েড স্টুডিওতে এই ইনলাইন মজাদারটিকে কাজ করতে পারি না। ঠিক আছে বলে মনে হচ্ছে তবে আমি যখন তা করি তবে তা স্বীকৃত হয় নাGson().fromJson<kotlin.List<Turns>>(pref.turns)
জুয়ান সরভিয়া

@ জুয়ানচো আপনি কি আমাকে "স্বীকৃত" মানে বলতে পারেন? একটি সংকলক ত্রুটি? আপনি কি এক্সটেনশন পদ্ধতিটি আমদানি করেছেন এবং উপরে থেকে উপলব্ধ?
জেইসন মিনার্ড

2
আমি আপনার কোডটি অ্যান্ড্রয়েড স্টুডিওতে অনুলিপি করেছি এবং আমার কোটলিন ক্লাসে মজাদার আমদানি করেছি। আপনি যা বলেছিলেন আমি তা করার চেষ্টা করেছি কিন্তু কোনও কারণে সংকলক আমাকে বলুন যে এই মজাটির অস্তিত্ব নেই। আমি ইতিমধ্যে অন্যান্য এক্সটেনশন ফাংশন ব্যবহার করছি তবে আপনার পরামর্শ কী কাজ করে তা আমি জানি না। আপনি এএস এবং কোটলিনের কোন সংস্করণ ব্যবহার করছেন? আবার চেষ্টা করার জন্য।
জুয়ান সরভিয়া

এটি সরাসরি অ্যান্ড্রয়েড স্টুডিওর সাথে সম্পর্কিত নয়, কোটলিন এর ভিতরে বা বাইরে একই। আপনি উদাহরণস্বরূপ তৈরি করছেন Gson()বা ঠিক Gsonযেমন স্থির? আপনার প্রথমটি প্রয়োজন, একটি উদাহরণ।
জেসন মিনার্ড

21

অন্য একটি বিকল্প (এটি অন্যদের তুলনায় আরও মার্জিত বলে নিশ্চিত নয়) এর জন্য এই কল হতে পারে:

turns = Gson().fromJson(allPurchasesString, Array<Turns>::class.java).toMutableList()

সুতরাং আপনি "খাঁটি কোটলিন" এর পরিবর্তে জাভা অ্যারে ক্লাস ওয়ান লাইনার ব্যবহার করছেন।


2
যেহেতু টাইপটোকেন প্রতিটি ফোনে নির্ভরযোগ্যভাবে কাজ করে না, এটি আমার পক্ষে সেরা সমাধান। খাঁটি কোটলিন সহ একটি সহজ একটি লাইনার।
লাকিমালাকা

11
val obj: MutableList<SaleItemResponse> = Gson().fromJson(messageAfterDecrypt,
    object : TypeToken<List<SaleItemResponse>>() {}.type)

কোটলিনে ডেটা অ্যারের পার্স করার এটি আমার উপায়।


এটি স্বীকৃত উত্তর, সংক্ষিপ্ত এবং সহজ হওয়া উচিত।
উমর আতা

6

আমি রূপান্তর Tকরতে stringএবং ব্যবহারে Stringফিরে যেতে এরকম কিছু Tব্যবহার করেছি Gson। আপনি যা খুঁজছেন ঠিক তা নয় তবে কেবল ক্ষেত্রে।

ঘোষণা বাড়ানো হচ্ছে

inline fun <reified T : Any> T.json(): String = Gson().toJson(this, T::class.java)
inline fun <reified T : Any> String.fromJson(): T = Gson().fromJson(this,T::class.java)

ব্যবহার

// Passing an object to new Fragment
companion object {    
        private const val ARG_SHOP = "arg-shop"

        @JvmStatic
        fun newInstance(shop: Shop) =
                ShopInfoFragment().apply {
                    arguments = Bundle().apply {
                        putString(ARG_SHOP, shop.json())
                    }
                }
    }

// Parsing the passed argument
private lateinit var shop: Shop

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.let {
            shop = it.getString(ARG_SHOP).fromJson() ?: return
        }
    }

5

এটি পাশাপাশি কাজ করে, এবং সহজ

    inline fun <reified T> Gson.fromJson(json: String) : T = 
         this.fromJson<T>(json, T::class.java)

রিটার্নের ধরণটি অবশ্যই আবশ্যক। অন্যথায় জিসন লাইব্রেরিতে জাভা কোডটি নালার দিকে ফিরে আসতে পারে, তবে কোটলিন অনুমান করে যে এই প্রকারটি অযোগ্য নয়। ফলস্বরূপ, আপনি কোটলিনে এনপিই পান।
fdermishin

1

Kotlin generic reified functionGson এর deserialize ArrayList<T>এই কোড ব্যবহার

 inline fun <reified T> get( ... ): ArrayList<T>{
    
    val str = "[{},{}]"
    
    val type = TypeToken.getParameterized(ArrayList::class.java, T::class.java).type
    
    val t = Gson().fromJson<ArrayList<T>>(str, type)
    

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