উচ্চ-অর্ডার ফাংশনগুলি খুব সহায়ক এবং তারা reusability
কোডের সত্যই উন্নতি করতে পারে । তবে এগুলি ব্যবহারের ক্ষেত্রে সবচেয়ে বড় উদ্বেগ হ'ল দক্ষতা। লাম্বদা এক্সপ্রেশন ক্লাসে সংকলিত হয় (প্রায়শই বেনামে ক্লাস হয়), এবং জাভাতে অবজেক্ট তৈরি করা একটি ভারী ক্রিয়াকলাপ। আমরা তবুও উচ্চতর অর্ডার ফাংশনগুলি কার্যকর উপায়ে ব্যবহার করতে পারি, সমস্ত সুবিধা বজায় রেখে ফাংশনগুলিকে ইনলাইন করে।
এখানে ছবিতে ইনলাইন ফাংশন আসে
যখন কোনও ফাংশন হিসাবে চিহ্নিত করা হয় inline
, কোড সংকলনের সময় সংকলক ফাংশনের আসল শরীরের সাথে সমস্ত ফাংশন কলগুলি প্রতিস্থাপন করবে। এছাড়াও, আর্গুমেন্ট হিসাবে প্রদত্ত ল্যাম্বদা এক্সপ্রেশনগুলি তাদের আসল শরীরের সাথে প্রতিস্থাপন করা হয়। তাদের ফাংশন হিসাবে বিবেচনা করা হবে না, তবে আসল কোড হিসাবে।
সংক্ষেপে: - ইনলাইন -> কল করার পরিবর্তে, তারা সংকলন সময়ে ফাংশনের বডি কোড দ্বারা প্রতিস্থাপিত হয় ...
কোটলিনে, অন্য ফাংশনের প্যারামিটার হিসাবে কোনও ফাংশন ব্যবহার করা (যা উচ্চতর অর্ডার ফাংশন হিসাবে পরিচিত) জাভা অপেক্ষা প্রাকৃতিক বোধ করে।
যদিও ল্যাম্বডাস ব্যবহারের কিছু অসুবিধা রয়েছে। যেহেতু তারা বেনাম শ্রেণি (এবং তাই বস্তু), তাই তাদের মেমরির প্রয়োজন (এবং এমনকি আপনার অ্যাপ্লিকেশনের সামগ্রিক পদ্ধতিতে এটি যোগ করতে পারে)। এড়াতে, আমরা আমাদের পদ্ধতিগুলি ইনলাইন করতে পারি।
fun notInlined(getString: () -> String?) = println(getString())
inline fun inlined(getString: () -> String?) = println(getString())
উপরের উদাহরণ থেকে : - এই দুটি ফাংশন ঠিক একই কাজ করে - getString ফাংশনের ফলাফল মুদ্রণ করে। একটি ইনলাইনড এবং অন্যটি নয়।
আপনি যদি পচা জাভা কোডটি পরীক্ষা করে দেখেন তবে দেখতে পাবেন যে পদ্ধতিগুলি সম্পূর্ণ অভিন্ন। কারণ ইনলাইন কীওয়ার্ডটি কল-সাইটে কোডটি অনুলিপি করার জন্য কম্পাইলারের নির্দেশ inst
তবে, যদি আমরা নীচের মতো অন্য ফাংশনে কোনও ফাংশনের ধরণটি পাস করি:
//Compile time error… Illegal usage of inline function type ftOne...
inline fun Int.doSomething(y: Int, ftOne: Int.(Int) -> Int, ftTwo: (Int) -> Int) {
//passing a function type to another function
val funOne = someFunction(ftOne)
/*...*/
}
এটি সমাধানের জন্য, আমরা নীচে হিসাবে আমাদের ফাংশনটি আবার লিখতে পারি:
inline fun Int.doSomething(y: Int, noinline ftOne: Int.(Int) -> Int, ftTwo: (Int) -> Int) {
//passing a function type to another function
val funOne = someFunction(ftOne)
/*...*/}
ধরুন আমাদের নীচের মতো উচ্চতর অর্ডার ফাংশন রয়েছে:
inline fun Int.doSomething(y: Int, noinline ftOne: Int.(Int) -> Int) {
//passing a function type to another function
val funOne = someFunction(ftOne)
/*...*/}
এখানে, সংকলকটি যখন কেবল একটি ল্যাম্বডা প্যারামিটার থাকে এবং আমরা এটিকে অন্য ফাংশনে পৌঁছে দিচ্ছি তখন ইনলাইন কীওয়ার্ডটি ব্যবহার না করতে আমাদের বলবে। সুতরাং, আমরা নীচের মত উপরের ফাংশনটি আবার লিখতে পারি:
fun Int.doSomething(y: Int, ftOne: Int.(Int) -> Int) {
//passing a function type to another function
val funOne = someFunction(ftOne)
/*...*/
}
দ্রষ্টব্য : -আমাদের পাশাপাশি কীওয়ার্ড নাইনলাইনও সরিয়ে ফেলতে হয়েছিল কারণ এটি কেবল ইনলাইন ফাংশনগুলির জন্যই ব্যবহার করা যেতে পারে!
মনে করুন আমাদের এর মতো ফাংশন রয়েছে ->
fun intercept() {
// ...
val start = SystemClock.elapsedRealtime()
val result = doSomethingWeWantToMeasure()
val duration = SystemClock.elapsedRealtime() - start
log(duration)
// ...}
এটি দুর্দান্ত কাজ করে তবে পরিমাপের কোডটির সাথে ফাংশনের যুক্তির মাংস দূষিত হয় যা আপনার সহকর্মীদের জন্য যা চলছে তা কাজ করা আরও শক্ত করে তোলে। :)
একটি ইনলাইন ফাংশন কীভাবে এই কোডটিকে সহায়তা করতে পারে তা এখানে:
fun intercept() {
// ...
val result = measure { doSomethingWeWantToMeasure() }
// ...
}
inline fun <T> measure(action: () -> T) {
val start = SystemClock.elapsedRealtime()
val result = action()
val duration = SystemClock.elapsedRealtime() - start
log(duration)
return result
}
এখন আমি পরিমাপের কোডের লাইন এড়িয়ে যাওয়া ছাড়া ইন্টারসেপ্ট () ফাংশনের মূল উদ্দেশ্য কী তা পড়তে মনোনিবেশ করতে পারি। আমরা যেখানে চাই সেখানে অন্য জায়গায় সেই কোডটি পুনরায় ব্যবহার করার বিকল্প থেকেও উপকৃত হই
ইনলাইন আপনাকে ল্যাম্বডা পরিমাপের মতো (মাইল্যামদা) পাস করার পরিবর্তে একটি বন্ধের (la ...}) মধ্যে ল্যাম্বডা যুক্তি দিয়ে একটি ফাংশন কল করতে দেয়