আমি প্রতিটি ফাংশন জন্য চালানোর জন্য একটি ভাল উদাহরণ আছে চান, এছাড়াও, প্রয়োগ, এছাড়াও ,.
আমি এই নিবন্ধটি পড়েছি তবে এখনও উদাহরণের অভাব রয়েছে
আমি প্রতিটি ফাংশন জন্য চালানোর জন্য একটি ভাল উদাহরণ আছে চান, এছাড়াও, প্রয়োগ, এছাড়াও ,.
আমি এই নিবন্ধটি পড়েছি তবে এখনও উদাহরণের অভাব রয়েছে
উত্তর:
এই সমস্ত ফাংশন বর্তমান ফাংশন / ভেরিয়েবলের স্কোপ পরিবর্তন করতে ব্যবহৃত হয়। এগুলি একসাথে সম্পর্কিত জিনিসগুলি রাখার জন্য ব্যবহৃত হয় (বেশিরভাগ সূচনা)।
এখানে কিছু উদাহরন:
run
- আপনার চাইলে যে কোনও কিছু ফেরত দেয় এবং এটিতে ব্যবহৃত ভেরিয়েবলটি আবার স্কোপ করে this
val password: Password = PasswordGenerator().run {
seed = "someString"
hash = {s -> someHash(s)}
hashRepetitions = 1000
generate()
}
পাসওয়ার্ড জেনারেটর এখন rescoped হয় this
এবং আমরা তাই সেট করতে পারেন seed
, hash
এবং hashRepetitions
একটি পরিবর্তনশীল ব্যবহার না করেই।
generate()
একটি উদাহরণ ফিরে আসবে Password
।
apply
অনুরূপ, তবে এটি ফিরে আসবে this
:
val generator = PasswordGenerator().apply {
seed = "someString"
hash = {s -> someHash(s)}
hashRepetitions = 1000
}
val pasword = generator.generate()
এটি বিল্ডার প্যাটার্নের প্রতিস্থাপন হিসাবে বিশেষত কার্যকর এবং যদি আপনি নির্দিষ্ট কনফিগারেশনগুলি পুনরায় ব্যবহার করতে চান।
let
- বেশিরভাগ নাল চেক এড়াতে ব্যবহৃত হয়, তবে এর প্রতিস্থাপন হিসাবেও ব্যবহার করা যেতে পারে run
। পার্থক্যটি হ'ল, এটি this
এখনও আগের মতোই থাকবে এবং আপনি পুনঃ-স্কোপড ভেরিয়েবলটি ব্যবহার করে এটি ব্যবহার করুন it
:
val fruitBasket = ...
apple?.let {
println("adding a ${it.color} apple!")
fruitBasket.add(it)
}
উপরের কোডটি কেবল আপেলটি ঝুড়িতে যুক্ত করবে কেবল যদি তা শূন্য না হয়। এছাড়াও লক্ষ্য করুন যে it
এখন আর alচ্ছিক নয় তাই আপনি এখানে নালপয়েন্টার এক্সসেপশনটি চালাবেন না (যেমন, ?.
এর বৈশিষ্ট্যগুলি অ্যাক্সেস করার জন্য আপনাকে ব্যবহার করার দরকার নেই )
also
- আপনি যখন ব্যবহার করতে চান এটি ব্যবহার করুন apply
, তবে ছায়া করতে চান নাthis
class FruitBasket {
private var weight = 0
fun addFrom(appleTree: AppleTree) {
val apple = appleTree.pick().also { apple ->
this.weight += apple.weight
add(apple)
}
...
}
...
fun add(fruit: Fruit) = ...
}
ব্যবহার apply
এখানে ছায়া হবে this
, যাতে this.weight
আপেল, এবং পড়ুন হবে না ফলের ঝুড়ি করতে।
দ্রষ্টব্য: আমি নির্লজ্জভাবে আমার ব্লগ থেকে উদাহরণগুলি নিয়েছি
কয়েকটি আরো নিবন্ধ মত এখানে ও এখানে যে কটাক্ষপাত করা মূল্য আছে।
আমি মনে করি যখন আপনার কয়েকটি লাইনের মধ্যে আরও সংক্ষিপ্ত, আরও সংক্ষিপ্ত প্রয়োজন হবে এবং শাখা বা শর্তসাপেক্ষ স্টেটমেন্ট চেকিং এড়াতে (যেমন নাল নয়, তবে এটি করুন) এটিকে কমিয়ে আনা হবে।
আমি এই সাধারণ চার্টটি পছন্দ করি, তাই আমি এটি এখানে লিঙ্ক করেছি। আপনি এটা থেকে দেখতে পারেন এই যেমন Sebastiano Gottardo দ্বারা লিখিত।
নীচে আমার ব্যাখ্যা সহ চার্টটিও দেখুন।
আপনি নিজের ফাংশনগুলি কল করার সময় আপনার কোড ব্লকের ভিতরে ভূমিকা রাখার উপায় হিসাবে আমি মনে করি + আপনি নিজেরাই ফিরে চান (কল ফাংশনগুলিতে চ্যানেল করতে চান, বা ফলাফল পরিবর্তনশীল ইত্যাদি)।
উপরে আমি কি মনে করি।
আসুন এখানে তাদের সবার জন্য উদাহরণগুলি দেখুন
১) এর myComputer.apply { }
অর্থ আপনি একজন প্রধান অভিনেতা হিসাবে অভিনয় করতে চান (আপনি নিজেকে কম্পিউটার মনে করতে চান), এবং আপনি নিজেকে ফিরে চান (কম্পিউটার) যাতে আপনি করতে পারেন
var crashedComputer = myComputer.apply {
// you're the computer, you yourself install the apps
// note: installFancyApps is one of methods of computer
installFancyApps()
}.crash()
হ্যাঁ, আপনি নিজেই কেবল অ্যাপ্লিকেশনগুলি ইনস্টল করেছেন, নিজেকে ক্রাশ করেছেন এবং অন্যকে এটির সাথে কিছু দেখতে এবং করার অনুমতি দেওয়ার জন্য নিজেকে রেফারেন্স হিসাবে সংরক্ষণ করেছেন।
২) এর myComputer.also {}
অর্থ আপনি সম্পূর্ণরূপে নিশ্চিত যে আপনি কম্পিউটার নন , আপনি বহিরাগত যে এটি দিয়ে কিছু করতে চায় এবং এটি একটি প্রত্যাশিত ফলাফল হিসাবে কম্পিউটারও চায়।
var crashedComputer = myComputer.also {
// now your grandpa does something with it
myGrandpa.installVirusOn(it)
}.crash()
৩) এর with(myComputer) { }
অর্থ আপনি মুখ্য অভিনেতা (কম্পিউটার), এবং আপনি নিজের ফলাফল হিসাবে নিজেকে চান না ।
with(myComputer) {
// you're the computer, you yourself install the apps
installFancyApps()
}
৪) এর myComputer.run { }
অর্থ আপনি প্রধান অভিনেতা (কম্পিউটার), এবং আপনি নিজের ফলাফল হিসাবে নিজেকে চান না want
myComputer.run {
// you're the computer, you yourself install the apps
installFancyApps()
}
তবে এটি with { }
খুব সূক্ষ্ম অর্থে পৃথক যে আপনি run { }
নীচের মত কল করতে পারেন
myComputer.run {
installFancyApps()
}.run {
// computer object isn't passed through here. So you cannot call installFancyApps() here again.
println("woop!")
}
এটি run {}
এক্সটেনশন ফাংশনটির কারণে , তবে with { }
তা নয়। সুতরাং আপনি কল করেছেন run { }
এবং this
কোড ব্লকের ভিতরে কলারের ধরণের অবজেক্টে প্রতিফলিত হবে। আপনি দেখতে পারেন এই মধ্যে পার্থক্য জন্য একটি চমৎকার ব্যাখ্যা জন্য run {}
এবং with {}
।
৫) এর myComputer.let { }
অর্থ আপনি বাইরের লোক যিনি কম্পিউটারটি দেখেন এবং কম্পিউটারের নজরে আবার আপনার কাছে ফিরে আসার জন্য কোনও যত্ন ছাড়াই এটি সম্পর্কে কিছু করতে চান।
myComputer.let {
myGrandpa.installVirusOn(it)
}
আমি বাহ্যিক, বাইরে যা কিছু দেখি also
এবং দেখি let
। আপনি যখনই এই দুটি শব্দটি বলছেন, এমন কোনও কিছু করার চেষ্টা করার মতো এটি। let
এই কম্পিউটারে ভাইরাস ইনস্টল করুন এবং also
এটি ক্রাশ করুন। সুতরাং এই নখগুলি আপনি অভিনেতা হন বা না হন তার অংশটি নিচে করে।
ফলাফল অংশের জন্য, এটি পরিষ্কারভাবে আছে। also
প্রকাশ করে যে এটি অন্য জিনিস, তাই আপনি এখনও অবজেক্টের উপলব্ধতা বজায় রেখেছেন। সুতরাং এটি ফলাফল হিসাবে এটি ফেরত।
অন্য সব কিছু জড়িত this
। অতিরিক্তভাবে run/with
স্পষ্টরূপে প্রত্যাবর্তন বস্তু স্ব-পিছনে আগ্রহী না doesn't এখন আপনি তাদের সকলের পার্থক্য করতে পারেন।
আমি মনে করি কখনও কখনও যখন আমরা উদাহরণস্বরূপ 100% প্রোগ্রামিং / যুক্তি-ভিত্তিক থেকে সরে যাই, তখন আমরা জিনিসগুলিকে ধারণা দেওয়ার পক্ষে আরও ভাল অবস্থানে থাকি। তবে এটি নির্ভর করে :)
কোটলিনে এক্সটেনশন ফাংশনগুলি হ'ল, এছাড়াও প্রয়োগ করুন, টেকআইফ করুন let
এই ফাংশনটি বুঝতে আপনাকে কোটলিনের এক্সটেনশন ফাংশন এবং ল্যাম্বদা ফাংশন বুঝতে হবে ।
এক্সটেনশন ফাংশন:
এক্সটেনশন ফাংশনটি ব্যবহার করে আমরা ক্লাসের উত্তরাধিকার সূত্রে ক্লাসের জন্য একটি ফাংশন তৈরি করতে পারি।
সি # এবং গোসুর অনুরূপ কোটলিন ক্লাসের উত্তরাধিকারী না হয়ে বা ডেকরেটারের মতো কোনও ধরণের ডিজাইনের প্যাটার্ন ব্যবহার না করেই নতুন কার্যকারিতা সহ একটি শ্রেণিকে প্রসারিত করার ক্ষমতা সরবরাহ করে। এটি এক্সটেনশন নামক বিশেষ ঘোষণার মাধ্যমে সম্পন্ন হয়। কোটলিন এক্সটেনশন ফাংশন এবং এক্সটেনশন বৈশিষ্ট্যগুলিকে সমর্থন করে।
সুতরাং, শুধুমাত্র সংখ্যায় রয়েছে কিনা তা খুঁজে পেতে String
, আপনি String
ক্লাসের উত্তরাধিকার না করে নীচের মতো একটি পদ্ধতি তৈরি করতে পারেন ।
fun String.isNumber(): Boolean = this.matches("[0-9]+".toRegex())
আপনি উপরের এক্সটেনশন ফাংশনটি এভাবে ব্যবহার করতে পারেন ,
val phoneNumber = "8899665544"
println(phoneNumber.isNumber)
যা প্রিন্ট হয় true
।
ল্যাম্বদা ফাংশন:
লাম্বদা ফাংশনগুলি ঠিক জাভাতে ইন্টারফেসের মতো। কিন্তু কোটলিনে লাম্বদা ফাংশনগুলি ফাংশনগুলির পরামিতি হিসাবে পাস করা যেতে পারে।
উদাহরণ:
fun String.isNumber(block: () -> Unit): Boolean {
return if (this.matches("[0-9]+".toRegex())) {
block()
true
} else false
}
আপনি দেখতে পাচ্ছেন, ব্লকটি ল্যাম্বদা ফাংশন এবং এটি প্যারামিটার হিসাবে পাস করা হয়। আপনি উপরের ফাংশনটি এভাবে ব্যবহার করতে পারেন,
val phoneNumber = "8899665544"
println(phoneNumber.isNumber {
println("Block executed")
})
উপরের ফাংশনটি এভাবে মুদ্রিত হবে,
Block executed
true
আমি আশা করি, আপনি এখন এক্সটেনশন ফাংশন এবং ল্যাম্বদা ফাংশন সম্পর্কে ধারণা পেয়েছেন। এখন আমরা একের পর এক এক্সটেনশন ফাংশনে যেতে পারি।
দিন
public inline fun <T, R> T.let(block: (T) -> R): R = block(this)
উপরের ফাংশনে দুটি প্রকারের টি এবং আর ব্যবহৃত হয়।
T.let
T
স্ট্রিং ক্লাসের মতো কোনও বস্তু হতে পারে। যাতে আপনি যে কোনও অবজেক্টের সাথে এই ফাংশনটি শুরু করতে পারেন।
block: (T) -> R
লেটের প্যারামিটারে, আপনি উপরের ল্যাম্বদা ফাংশনটি দেখতে পারেন। এছাড়াও, আমন্ত্রণকারী বস্তুটি ফাংশনের প্যারামিটার হিসাবে পাস করা হয়। সুতরাং আপনি ফাংশন ভিতরে চালিত শ্রেণি অবজেক্ট ব্যবহার করতে পারেন। তারপরে এটি R
(অন্য কোনও বস্তু) প্রদান করে।
উদাহরণ:
val phoneNumber = "8899665544"
val numberAndCount: Pair<Int, Int> = phoneNumber.let { it.toInt() to it.count() }
উপরোক্ত উদাহরণে এলইটি লাগে স্ট্রিং তার ল্যামডা ফাংশন একটি প্যারামিটার হিসাবে এবং এটি ফেরৎ জুড়ি বিনিময়ে।
একইভাবে, অন্যান্য এক্সটেনশন ফাংশন কাজ করে।
এছাড়াও
public inline fun <T> T.also(block: (T) -> Unit): T { block(this); return this }
এক্সটেনশন ফাংশনটি also
ল্যাম্বদা ফাংশন প্যারামিটার হিসাবে চালিত শ্রেণিকে গ্রহণ করে এবং কিছুই দেয় না।
উদাহরণ:
val phoneNumber = "8899665544"
phoneNumber.also { number ->
println(number.contains("8"))
println(number.length)
}
প্রয়োগ
public inline fun <T> T.apply(block: T.() -> Unit): T { block(); return this }
একই একই তবে একই অনুরোধযুক্ত বস্তুটি ফাংশন হিসাবে পাস হয়েছে যাতে আপনি এটি বা প্যারামিটারের নাম না বলে ফাংশন এবং অন্যান্য বৈশিষ্ট্যগুলি ব্যবহার করতে পারেন।
উদাহরণ:
val phoneNumber = "8899665544"
phoneNumber.apply {
println(contains("8"))
println(length)
}
উপরের উদাহরণে আপনি দেখতে পারেন স্ট্রিং ক্লাসের ফাংশনগুলি সরাসরি ল্যাম্বদা ফান্টের অভ্যন্তরে ডাকা হয়েছিল।
টেকআইফ
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
উদাহরণ:
val phoneNumber = "8899665544"
val number = phoneNumber.takeIf { it.matches("[0-9]+".toRegex()) }
উপরের উদাহরণে এটির সাথে মেলে কেবল number
একটি স্ট্রিং । অন্যথায়, এটি হবে ।phoneNumber
regex
null
গ্রহণহীন
public inline fun <T> T.takeUnless(predicate: (T) -> Boolean): T? = if (!predicate(this)) this else null
এটি টেকআইফের বিপরীত।
উদাহরণ:
val phoneNumber = "8899665544"
val number = phoneNumber.takeUnless { it.matches("[0-9]+".toRegex()) }
number
এর সাথে phoneNumber
মেলে না শুধুমাত্র তার একটি স্ট্রিং থাকবে regex
। অন্যথায়, এটি হবে null
।
আপনি একই রকম উত্তর দেখতে পারেন যা এখানে দরকারী , কোটলিনের মধ্যে প্রয়োগ, দেওয়া, ব্যবহার, টেকআইফ এবং গ্রহণহীনতার মধ্যে পার্থক্য difference
phoneNumber. takeUnless{}
পরিবর্তে বোঝাতে চেয়েছিলেন phoneNumber. takeIf{}
।
এখানে 6 টি বিভিন্ন স্কোপিং ফাংশন রয়েছে:
আমি পার্থক্যগুলি দেখানোর জন্য নীচের হিসাবে একটি ভিজ্যুয়াল নোট প্রস্তুত করেছি:
data class Citizen(var name: String, var age: Int, var residence: String)
সিদ্ধান্ত আপনার প্রয়োজনের উপর নির্ভর করে। বিভিন্ন ফাংশনের ব্যবহারের ক্ষেত্রে ওভারল্যাপ হয়, যাতে আপনি আপনার প্রকল্প বা দলে ব্যবহৃত নির্দিষ্ট সম্মেলনের উপর ভিত্তি করে ফাংশনগুলি চয়ন করতে পারেন।
যদিও স্কোপ ফাংশনগুলি কোডটি আরও সংক্ষিপ্ত করার একটি উপায়, সেগুলি অতিরিক্ত ব্যবহার করা এড়িয়ে চলুন: এটি আপনার কোডের পঠনযোগ্যতা হ্রাস করতে পারে এবং ত্রুটির দিকে পরিচালিত করতে পারে। বাসা বেঁধে দেওয়ার সুযোগগুলি এড়িয়ে চলুন এবং তাদের শৃঙ্খলাবদ্ধ হওয়ার সময় সাবধানতা অবলম্বন করুন: বর্তমান প্রসঙ্গের অবজেক্ট এবং এটি বা এর মূল্য সম্পর্কে বিভ্রান্ত হওয়া সহজ।
Https://medium.com/@elye.project/mastering-kotlin-standard-function-run-with-let-also-and-apply-9cd334b0ef84 থেকে কোনটি ব্যবহার করবেন তা সিদ্ধান্ত নেওয়ার জন্য এখানে আরও একটি চিত্র রয়েছে
কয়েকটি সম্মেলন নিম্নলিখিত হিসাবে রয়েছে:
অতিরিক্ত ক্রিয়াকলাপগুলির জন্যও ব্যবহার করুন যা অবজেক্টকে পরিবর্তন করে না, যেমন লগিং বা ডিবাগের তথ্য মুদ্রণ করা।
val numbers = mutableListOf("one", "two", "three")
numbers
.also { println("The list elements before adding new one: $it") }
.add("four")
প্রয়োগের জন্য সাধারণ ক্ষেত্রে হ'ল অবজেক্ট কনফিগারেশন।
val adam = Person("Adam").apply {
age = 32
city = "London"
}
println(adam)
আপনার যদি শেডিংয়ের প্রয়োজন হয়, রান ব্যবহার করুন
fun test() {
var mood = "I am sad"
run {
val mood = "I am happy"
println(mood) // I am happy
}
println(mood) // I am sad
}
আপনি যদি রিসিভার অবজেক্ট নিজেই ফেরত নিতে চান তবে প্রয়োগ করুন বা এটিও ব্যবহার করুন
আমার অভিজ্ঞতা অনুযায়ী, যেহেতু এই জাতীয় ফাংশনগুলি কোনও পারফরম্যান্সের পার্থক্য ছাড়াই ইনলাইন সিনট্যাকটিক চিনি, তাই আপনার সর্বদা ল্যামডায় ন্যূনতম পরিমাণের কোড লেখার প্রয়োজন এমন একটি চয়ন করা উচিত।
এটি করার জন্য, প্রথমে আপনি নির্ধারণ করুন যে আপনি ল্যাম্বদা তার ফলাফল (চয়ন run
/ বেছে নিতে পারেন let
) অথবা নিজেই বস্তুটি (চয়ন apply
/ বেছে নিন) চান কিনা also
; তারপরে বেশিরভাগ ক্ষেত্রে যখন ল্যাম্বডা একটি একক অভিব্যক্তি হয় তবে সেই একই ব্লক ফাংশন টাইপের একটিকে সেই অভিব্যক্তি হিসাবে বেছে নিন, কারণ এটি যখন রিসিভারের এক্সপ্রেশন হয় this
তখন বাদ দেওয়া যায়, যখন এটি প্যারামিটারের এক্সপ্রেশন it
হয় তার চেয়ে কম হয় this
:
val a: Type = ...
fun Type.receiverFunction(...): ReturnType { ... }
a.run/*apply*/ { receiverFunction(...) } // shorter because "this" can be omitted
a.let/*also*/ { it.receiverFunction(...) } // longer
fun parameterFunction(parameter: Type, ...): ReturnType { ... }
a.run/*apply*/ { parameterFunction(this, ...) } // longer
a.let/*also*/ { parameterFunction(it, ...) } // shorter because "it" is shorter than "this"
যাইহোক, ল্যাম্বদা যখন সেগুলির সাথে মিশ্রিত হয়, তখন প্রসঙ্গের সাথে আরও ভাল ফিট করা বা আপনি আরও স্বাচ্ছন্দ্য বোধ করেন এমন একটি চয়ন করা আপনার পক্ষে।
এছাড়াও, ডিকানস্ট্রাকশন প্রয়োজন হলে প্যারামিটার ব্লক ফাংশনযুক্তগুলি ব্যবহার করুন:
val pair: Pair<TypeA, TypeB> = ...
pair.run/*apply*/ {
val (first, second) = this
...
} // longer
pair.let/*also*/ { (first, second) -> ... } // shorter
এখানে জাভাব্রেইনসের জাভা ডেভেলপারদের কোর্সেরা কোটলিনে অফিসিয়াল কোটলিন কোর্স থেকে এই সমস্ত ফাংশনের মধ্যে একটি সংক্ষিপ্ত তুলনা দেওয়া হল :