Kotlin में मेटाप्रोग्रामिंग: रिफ्लेक्शन से कोड जनरेशन तक

शुरुआती लोगों के लिए ऑनलाइन Python प्रशिक्षक

Python आसानी से सीखें बिना सिद्धांत के बोझ के। स्वचालित जांच के साथ व्यावहारिक कार्य हल करें और ब्राउज़र में सीधे कोड लिखें।

पाठ्यक्रम शुरू करें

Kotlin में मेटाप्रोग्रामिंग: कोड को कोड लिखने के लिए कैसे प्रेरित करें

\n\n

कल्पना करें कि आप ऐसा कोड लिख रहे हैं जो खुद कोड लिखता है। क्या यह विज्ञान कथा जैसा लगता है? Kotlin में मेटाप्रोग्रामिंग की दुनिया में यह वास्तविकता है। मेटाप्रोग्रामिंग एक तकनीक है जिसमें प्रोग्राम स्वयं या अन्य प्रोग्रामों को डेटा के रूप में हेरफेर करता है। Kotlin डेवलपर के लिए, यह एक सुपरपावर है जो टनों बॉयलरप्लेट कोड को कम करने, लचीले फ्रेमवर्क बनाने और दिनचर्या को स्वचालित करने की अनुमति देता है।

\n\n

इस लेख में, हम Kotlin में मेटाप्रोग्रामिंग की उन्नत तकनीकों पर चर्चा करेंगे: क्लासिकल रिफ्लेक्शन से लेकर KSP के साथ आधुनिक कोड जनरेशन तक। आप सीखेंगे कि रिफाइड टाइप्स, इनलाइन-फंक्शन, एनोटेशन और बहुत कुछ का उपयोग कैसे करें। चलिए शुरू करते हैं!

\n\n

Kotlin में रिफ्लेक्शन: हुड के नीचे झाँकना

\n\n

रिफ्लेक्शन मेटाप्रोग्रामिंग की नींव है। Kotlin में, इसे kotlin-reflect लाइब्रेरी के माध्यम से कार्यान्वित किया जाता है। इसकी मदद से, रनटाइम के दौरान क्लासेस, फंक्शन और प्रॉपर्टीज के बारे में गतिशील रूप से जानकारी प्राप्त की जा सकती है।

\n\n

उदाहरण: मान लीजिए, आपको किसी ऑब्जेक्ट को JSON में सीरियलाइज़ करना है, बिना पहले उसके प्रकार को जाने। रिफ्लेक्शन इसे संभव बनाता है:

\n\n
import kotlin.reflect.full.memberProperties\n\nfun toJson(obj: Any): String {\n    val sb = StringBuilder("{")\n    val props = obj::class.memberProperties\n    props.forEachIndexed { index, prop ->\n        sb.append("\\"${prop.name}\\": \\"${prop.get(obj)}\\"")\n        if (index < props.size - 1) sb.append(", ")\n    }\n    sb.append("}")\n    return sb.toString()\n}\n\ndata class User(val name: String, val age: Int)\n\nfun main() {\n    val user = User("आलिसा", 30)\n    println(toJson(user)) // {"name": "आलिसा", "age": "30"}\n}\n
\n\n

यह एक बुनियादी लेकिन शक्तिशाली तकनीक है। हालांकि, रिफ्लेक्शन में एक कमी है - प्रदर्शन। उच्च-लोड सिस्टम के लिए, कोड जनरेशन का उपयोग करना बेहतर है, जिसके बारे में हम बाद में बात करेंगे।

\n\n

इनलाइन-फंक्शन और रिफाइड टाइप्स

\n\n

मेटाप्रोग्रामिंग के लिए Kotlin की सबसे शानदार क्षमताओं में से एक रिफाइड (reified) टाइप्स हैं। वे केवल इनलाइन-फंक्शन के अंदर काम करते हैं और रनटाइम के दौरान टाइप के बारे में जानकारी संरक्षित करने की अनुमति देते हैं, जो JVM में टाइप इरेज़र के कारण सामान्यतः असंभव है।

\n\n

देखें कि रनटाइम पर कितनी आसानी से टाइप प्राप्त किया जा सकता है:

\n\n
inline fun <reified T> typeName(): String {\n    return T::class.simpleName ?: "Unknown"\n}\n\nfun main() {\n    println(typeName<String>())   // String\n    println(typeName<List<Int>>()) // List\n}\n
\n\n

reified के बिना, यह करतब काम नहीं करेगा - कंपाइलर बस टाइप मिटा देगा। और इस तकनीक की मदद से, आप टाइप की गई फैक्ट्रीज़, सीरियलाइज़र और यहां तक कि पूरे फ्रेमवर्क बना सकते हैं। यह वास्तव में Kotlin में रिफाइड टाइप का कार्यान्वयन है।

\n\n

एनोटेशन: मेटाडेटा के लिए आपका निजी DSL

\n\n

Kotlin में एनोटेशन केवल मार्कर नहीं हैं। रिफ्लेक्शन या कोड जनरेशन के साथ मिलकर, वे मेटाप्रोग्रामिंग के एक शक्तिशाली उपकरण में बदल जाते हैं। आइए वैलिडेशन के लिए अपना खुद का एनोटेशन बनाएं:

\n\n
@Target(AnnotationTarget.FIELD)\n@Retention(AnnotationRetention.RUNTIME)\nannotation class NotBlank(val message: String = "फ़ील्ड खाली नहीं होनी चाहिए")\n\nfun validate(obj: Any): List<String> {\n    val errors = mutableListOf<String>()\n    obj::class.memberProperties.forEach { prop ->\n        val annotation = prop.findAnnotation<NotBlank>()\n        if (annotation != null) {\n            val value = prop.get(obj) as? String\n            if (value.isNullOrBlank()) {\n                errors.add("${prop.name}: ${annotation.message}")\n            }\n        }\n    }\n    return errors\n}\n\ndata class Form(val name: String, @NotBlank val email: String)\n\nfun main() {\n    val form = Form("इवान", "")\n    println(validate(form)) // [email: फ़ील्ड खाली नहीं होनी चाहिए]\n}\n                

ब्लॉग

पुस्तक अनुशंसाएँ