Swift: Overloading ~=
আমরা swift এ বিভিন্ন কাজে প্যাটার্ন ম্যাচিং ব্যবহার করি। আমার যখন কোন দুইটা ভ্যালু তুলনা করি তখন কম্পাইলার == ব্যবহার করে উভয় দিক তুলনা করে।কিন্তু অনেক সময় ভ্যালু দুইটা একই টাইপ না হয়ে ভিন্ন টাইপ হতে পারে। যেমনঃ
let range = 1...30
let a = 14
এখানে যদি আমরা তুলনা করতে যাই প্যাটার্ন ম্যাচিং এর সাহায্যে, যেমন,
if case 1...30 = a{
print("In Range") // true
}
এখানে কম্পাইলার ~= অপারেটর ব্যবহার করে চেক করছে যে, a কি 1…30 মধ্যে আছে কিনা।থাকলে true রিটার্ন করছে তা থাকলে false । আমরা চাইলে এটা সরাসরি এভাবে লিখতে পারি।
let inRange = (1...10 ~= 4) // true
কিন্তু আমরা যদি [String] সাথে একটা String তুলনা করতে যাই তাহলে কি হবে ?
let names = ["Karim","Rahim","Jalal","Kamal"]
let name = "Jaif" // Expression pattern of type '[String]' cannot match values of type 'String'
if case names = name{
print("In There")
}
ইরর আসছে।এখন আমাদের ~= অপারেটরকে overload করতে হবে যাতে সেটা String এর ক্ষেত্রেও কাজ করে। না হলে আমাদের তথাগত উপায়ে করতে হবে চেক করার জন্য। যেমনঃ
for i in names where i == name{
print("In There") // In There
}
for case name in names{
print("In There") // In There
}
let isContain = names.contains(name) // true
এখন ~= অপারেটরের এর সাহায্যে বের করতে হলে আমাদের নিচের কোডটি লিখে ফেলতে হবে যাতে কম্পাইলার বুঝতে পারে এবং String এর ক্ষেত্রেও কাজ করে।
func ~=(pattern: [String], lookUp: String) -> Bool{
for i in pattern where i == lookUp {
return true
}
return false
}
এখন যদি আমরা পুনরায় আগের কোডটি লিখি ফেলি তাহলে আমরা দেখব সেটা কাজ করছে।
if case names = name{
print("In There") // In There
}
isContain = (names ~= name) // true
এখন আমরা খুব সহজেই চেক করতে পারব প্যাটার্ন ম্যাচিং এর সাহায্যে।কিন্তু, একটা সমস্যা রয়ে গেলো। আমরা যদি এখন String ভিন্ন অন্য কোন কিছু যেমন [Int] এর সাথে Int করতে যাই তাহলে আবার ইরর আসবে।আমাদের ~= অপারেটরকে আবার overload করতে হবে Int এর সাথে কাজ করার জন্য ? তাহলে এখন আমরা কি করবো ? আমরা কি আবার Int এর জন্য override করবো ? ধরা যাক, পরবর্তীতে আবার Double এর জন্যও লাগল ? কিম্বা আমাদের কোন কাস্টম টাইপর জন্য? আমরা কি বার বার একেক টাইপের জন্য overload করবো?
না ! আমরা প্রোগ্রামার, আমরা কেন এত কষ্ট করবো? আমরা জেনেরিক টাইপ overload করবো! তাহলেই আমাদের যেকোনো টাইপর জন্য কাজ করবে ! কিন্তু ? আচ্ছা আগে কোড টা লিখে ফেলি!
func ~=<T: Equatable>(pattern: [T], lookUp: T) -> Bool{
for i in pattern where i == lookUp {
return true
}
return false
}
এখানে আমরা Equatable protocol কনফর্ম করেছি।কারণ কি? আমরা যদি ভালো ভাবে দেখি আমরা মূলত == সাহায্যে লুপিং করে চেক করছি।এখন যদি আমাদের টাইপ == দ্বারা চেক না করা যায় তাহলে ? আমাদের overload কাজ করবে না। ইরর আসবে। সেজন্য আমাদের নিশ্চিত হতে হবে যে আমাদের টাইপ == দ্বারা চেক করা সম্ভব। Int, String, Double, UInt32 ইত্যাদির ক্ষেত্রে Equatable বিল্ড ইন করা আছে। ফলে আমাদের আর মাথা ঘামাতে হবে না। কিন্তু যদি আমরা কোন কাস্টম টাইপ ব্যবহার করি ? তাহলে ?
আমাদের ঐ টাইপ কে Equatable protocol কে কনফর্ম করাতে হবে। যেমনঃ
struct Person: Equatable{
let name: String
let age: Int
init(name: String,age: Int) {
self.name = name
self.age = age
}
}
আমরা যদি Equatable protocol কে কনফর্ম না করি এবং নিচের কোড লিখি তাহলে,
let isPersonHere = (persons ~= person) // Binary operator '~=' cannot be applied to operands of type '[Person]' and 'Person'
এই জন্য আমাদের আগে Equatable protocol কে কনফর্ম করতে হবে। যদি এখন আমরা পুনরায় রান দেই তাহলে দেখব আমাদের কোড কাজ করছে।
এভাবে, আমরা ~= অপারেটরকে overloading এর মাধ্যমে প্রায় যেকোনো টাইপের ক্ষেত্রে ব্যবহার করতে পারব। আজ এই পর্যন্তই।
0 Comments