Generic — জেনারিক টাইপের সার ও T প্যারামিটার

লেখক: IT Sectr প্রকাশিত: 2026-06-18 পড়ার সময়: 10 মিনিট

Generic (জেনারিক প্রোগ্রামিং) — Swift এর একটি প্রক্রিয়া যা প্যারামিটারাইজড টাইপ সহ টাইপ ও ফাংশন লেখার অনুমতি দেয়। Int, String ও কাস্টম গঠনের জন্য কোড দুবার করার পরিবর্তে, ডিভেলপার একটি সামান্য সমাধান তৈরি করে যা যে কোনো টাইপের সাথে কাজ করে, সাথে সাথে স্ট্রিক্ট টাইপিং বজায় রাখে। কম্পাইলার ব্যবহারের সময় নির্দিষ্ট টাইপ প্রতিস্থাপন করে, যা পরিবেশন হারিয়ে নিরাপত্তা নিশ্চিত করে। Swift Book, 2025 অনুযায়ী, generic প্যারামিটার ভাষার একটি গুরুত্বপূর্ণ বৈশিষ্ট্য, যা স্ট্যান্ডার্ড লাইব্রেরি ও SwiftUI এর ভিত্তি গঠন করে।

মূল বিষয়সমূহ

  • Generic — টাইপ প্যারামিটার সহ জেনারিক প্রোগ্রামিং প্রক্রিয়া
  • ফাংশন generic প্যারামিটার সহ কোড দুবার ছাড়া যে কোনো টাইপের সাথে কাজ করে
  • where সীমাবদ্ধি generic কে শর্ত পূরণ করে এমন টাইপের মধ্যে সীমিত করে
  • Associated Types প্রোটোকলে প্রোটোকলকে জেনারিক হতে দেয়
  • কম্পাইলার প্রতিটি নির্দিষ্ট টাইপের জন্য বিশেষায়ন কোড উত্পাদন করে

Swift এ Generic কি?

Generic (জেনারিক টাইপ) — Swift এর একটি ব্যাকরণিক গঠন যা টাইপ প্যারামিটারাইজেশন সহ নমনীয়, পুনর্ব্যবহার্য কোড লেখার অনুমতি দেয়। একটি নির্দিষ্ট টাইপের পরিবর্তে, কোণাকার ব্র্যাকেটে একটি প্লেসহোল্ডার লেখা হয় — সাধারণত , কিন্তু যে কোনো নাম ব্যবহার করা যেতে পারে। Generics SwiftUI (View, some View), স্ট্যান্ডার্ড লাইব্রেরি (Array, Optional) ও Combine এর ভিত্তি গঠন করে।

জেনারিক্স কেন প্রয়োজন

জেনারিক্স ছাড়া, আপনাকে প্রতিটি টাইপের জন্য পৃথক ফাংশন লিখতে হবে: swapInts, swapStrings, swapDates । একটি generic swap ফাংশন একটি ঘোষণার মাধ্যমে তিনটি ভ্যারিয়েন্টকে প্রতিস্থাপন করে। এটি দুবারের পরিমাণ হ্রাস করে, পড়ার সুবিধা বাড়ায় ও কোড কপি করার সময় ত্রুটির সম্ভাবনা হ্রাস করে।

swift
func swapValues<T>(_ a: inout T, _ b: inout T) {
    let temp = a
    a = b
    b = temp
}

var x = 10
var y = 20
swapValues(&x, &y)

Swift কম্পাইলার generic এর প্রতিটি নির্দিষ্ট ব্যবহারের জন্য বিশেষায়ন কোড উত্পাদন করে। এর মানে হল generic ফাংশন swapValues এর Int এর জন্য হাতে লেখা ফাংশনের তুলনায় কোনো ওভারহেড নেই। Swift Java এর মতো টাইপ ইরেজার ব্যবহার করে না — generics কম্পাইল টাইম ও রানটাইম উভয়ই বিদ্যমান (যদিও অপ্টিমাইজেশন তাদের বিশেষায়ন করতে পারে)।

প্যারামিটার T সহ জেনারিক ফাংশন

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

একাধিক টাইপ প্যারামিটার

একটি ফাংশনের একাধিক generic প্যারামিটার থাকতে পারে। উদাহরণস্বরূপ, ফাংশন findKey চাবি K ও মান V সহ একটি অভিধান গ্রহণ করে। প্রতিটি টাইপ প্যারামিটার অনন্য ও সীমাবদ্ধিতে ব্যবহৃত হতে পারে।

swift
func findKey<K: Hashable, V>(
    for value: V,
    in dictionary: [K: V]
) -> K? where V: Equatable {
    for (key, dictValue) in dictionary {
        if dictValue == value {
            return key
        }
    }
    return nil
}

সীমাবদ্ধি K: Hashable ও where V: Equatable নিশ্চিত করে যে findKey কেবল এমন একটি অভিধানের সাথে ডাকা যেতে পারে যার চাবি হ্যাশেবল ও মান ইক্যুইটেবল । এমন সীমাবদ্ধি আমলতন্ত্র নয়, বরং অপরিহার্য: Hashable ছাড়া আপনি চাবি অনুসন্ধান ইনডেক্স করতে পারবেন না, Equatable ছাড়া আপনি dictValue এর সাথে value তুলনা করতে পারবেন না।

where এর মাধ্যমে টাইপ সীমাবদ্ধি

where — Swift এর একটি কীওয়ার্ড যা generic প্যারামিটারের উপর অতিরিক্ত সীমাবদ্ধি বেশ করে। কোণাকার ব্র্যাকেট () এ শুধুমাত্র একটি প্রোটোকল নির্দিষ্ট করার বিপরীতে, where আরও জটিল শর্ত প্রকাশ করতে দেয়: একাধিক প্রোটোকলের অনুসরণ, টাইপ প্যারামিটারের মধ্যে সম্পর্ক ও সংশ্লিষ্ট টাইপের পরিষ্কার।

where সিনট্যাক্স

where ক্লজ় ফাংশন বা টাইপের সিগনেচারের পরে, খুলনা ব্রেসের আগে লেখা হয়। where এ আপনি নির্দিষ্ট করতে পারেন যে T: Comparable & Hashable (একটি সাথে দুটি প্রোটোকলের অনুসরণ করে), বা T.U == Int (একটি সংশ্লিষ্ট টাইপ নির্দিষ্ট করে)।

swift
protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int { get }
}

extension Container where Item: Comparable {
    func isSorted() -> Bool {
        // Implementation available only if Item: Comparable
        return true
    }
}

where সহ এক্সটেনশন কেবল সেই টাইপগুলোর জন্য পদ্ধতি যোগ করে যারা শর্ত পূরণ করে। Container isSorted পদ্ধতি পাবে, কিন্তু Container পাবে না, কারণ Any Comparable নয়। এটি শর্তমূলক কার্যকারিতার একটি শক্তিশালী প্রক্রিয়া।

প্রোটোকলে Associated Types

Associated Types (সংশ্লিষ্ট টাইপ) — একটি প্রোটোকলকে ঘোষণার সময় নির্দিষ্ট টাইপ উল্লেখ না করে জেনারিক করার একটি উপায়। এর পরিবর্তে, প্রোটোকল একটি associatedtype ঘোষণা করে, যা বাস্তবায়নে নির্দিষ্ট হয়। এটি বিশেষ করে সংগ্রহের জন্য গুরুত্বপূর্ণ: Sequence প্রোটোকল জানে না যে অনুক্রমটিতে কি কি উপাদান থাকবে।

where এর মাধ্যমে Associated Types সংযোগ

where ব্যবহার করে আপনি বিভিন্ন প্রোটোকলের associated types এর মধ্যে সম্পর্ক স্থাপনা করতে পারেন। উদাহরণস্বরূপ, আপনি দাবি করতে পারেন যে একটি প্রোটোকলের Item অন্যটির Iterator.Element এর সাথে মেলাছে। এটি কম্পাইলার স্তরে টাইপ সামঞ্জস্য নিশ্চিত করে।

swift
protocol StackProtocol {
    associatedtype Element
    mutating func push(_ item: Element)
    mutating func pop() -> Element?
}

struct IntStack: StackProtocol {
    typealias Element = Int
    private var items: [Int] = []
    
    mutating func push(_ item: Int) { items.append(item) }
    mutating func pop() -> Int? { items.popLast() }
}

IntStack typealias ব্যবহার করে Element কে Int হিসাবে নির্দিষ্ট করে। কম্পাইলার যাচাই করে যে এই টাইপের সাথে প্রোটোকলের সকল আবশ্যকতা পূরণ হয়। associated types ছাড়া, আপনাকে একটি generic প্রোটোকলের সাথে StackProtocol লিখতে হবে, কিন্তু Swift Objective-C ব্রিজ এর সাথে সঙ্গতিশীলতা ও উন্নত পড়ার সুবিধার জন্য associated types ব্যবহার করে।

এক্সটেনশন ও সাবস্ক্রিপ্টে Generic

Generic এক্সটেনশন অতিরিক্ত সীমাবদ্ধি সহ একটি generic টাইপে পদ্ধতি যোগ করার অনুমতি দেয়। এটি হল শর্তমূলক অনুরূপণ পৈটার্ন, যেখানে একটি টাইপ কেবল নির্দিষ্ট শর্তে কার্যকারিতা পায়। সাবস্ক্রিপ্ট ও generic হতে পারে।

Generic সাবস্ক্রিপ্ট

একটি সাবস্ক্রিপ্ট generic হতে পারে: এটি কোণাকার ব্র্যাকেটে generic প্যারামিটার গ্রহণ করে। এটি এমন কর্বনাপসন্দ ইনডেক্স সহ সংগ্রহে নিরাপদ প্রবেশের জন্য উপযোগী, যেখানে ইনডেক্স বিভিন্ন টাইপের হতে পারে।

swift
extension Array where Element: Numeric {
    func sum() -> Element {
        return reduce(0, +)
    }
}

extension Array {
    subscript<Indices: Sequence>(indices: Indices) -> [Element]
        where Indices.Element == Int {
        return indices.map { self[$0] }
    }
}

এই গঠন শক্তিশালী কম্পোজিশন প্রদান করে: sum পদ্ধতি কেবল সংখ্যামূলক অ্যারেতে উপস্থিত হয়, এবং কর্বনাপসন্দ ইনডেক্স সহ সাবস্ক্রিপ্ট পূর্ণাংক ইনডেক্সের যে কোনো অনুক্রমের সাথে কাজ করে। কম্পাইলার where শর্তের উপর ভিত্তি করে এই সদস্যগুলির দৃশ্যমানতা নিয়ন্ত্রণ করে।

Generic নিয়ে কাজ করার সময় সাধারণ ভুল

ভুল generic ব্যবহার করার সময় প্রায়ই ভুল সীমাবদ্ধি বা যেখানে নির্দিষ্ট টাইপ প্রয়োজন সেখানে generic ব্যবহারের চেষ্টার সাথে সম্পর্কিত। আসুন তিনটি সাধারণ পরিদৃশ্য দেখি যা ডিভেলপারদের সমাধান করতে হয়।

অতিরিক্ত প্যারামিটারাইজেশন

যেখানে নির্দিষ্ট টাইপ যথেষ্ট সেখানে generic প্যারামিটার যোগ করা একটি অনাতস্ব নমুনা। যদি একটি ফাংশন সব সময় String নিয়ে কাজ করে, তবে এটিকে করার প্রয়োজন নেই। এটি কোডকে কোনো লাভ ছাড়া জটিল করে। Generic যখন নিয়োজ্য যখন টাইপ প্রকৃতিভাবে ভিন্ন হয়, ব্যর্থ ভবিষ্যতের নমনীয়তার জন্য নয়।

where সীমাবদ্ধির অনুপস্থিতি

একটি generic প্যারামিটারে একটি পদ্ধতি কেল করা যে পদ্ধতিটি বিদ্যমান তা নির্দিষ্ট না করে একটি ত্রুটি। .count কেল করতে পারে না যদি T: Collection নিර্দিষ্ট না হয়। সব সময় টাইপ প্যারামিটারে সীমাবদ্ধি যোগ করুন, অন্যথা কম্পাইলার কোড প্রত্যাখ্যান করবে।

swift
// ❌ Error: value has no count method
func countElements<T>(value: T) -> Int { value.count }

// ✅ Works: T: Collection guarantees count exists
func countElements<T: Collection>(value: T) -> Int { value.count }

ত্রুটিটি স্পষ্ট: generic যে কোনো টাইপ হতে পারে, এবং কম্পাইলার জানে না যে এর count আছে কিনা। Collection সীমাবদ্ধি সমস্যা সমাধান করে। একইভাবে Equatable, Hashable, Numeric এর জন্যও — যদি আপনি generic প্যারামিটারে পদ্ধতি বা অপারেটর কেল করার পরিকল্পনা করেন তবে সব সময় প্রোটোকল নির্দিষ্ট করুন।

সাধারণজিজ্ঞাসিত প্রশ্ন

সাধারণ ভাষায় Swift এ Generic কি?

Generic হল কোড লেখার একটি উপায় যা যে কোনো টাইপের সাথে কাজ করে, Int, String ও অন্যান্য টাইপের জন্য একই যুক্তি দুবার না করে। একটি নির্দিষ্ট টাইপের পরিবর্তে, একটি প্লেসহোল্ডার ব্যবহৃত হয়, যা ব্যবহারের সময় প্রকৃত টাইপ দ্বারা প্রতিস্থাপিত হয়।

Generic কিভাবে Any থেকে আলাদা?

Generic কম্পাইল টাইমে নির্দিষ্ট টাইপের তথ্য সংরক্ষণ করে, যা কম্পাইলারকে টাইপ যাচাই ও অপ্টিমাইজড কোড উত্পাদনের অনুমতি দেয়। Any হল টাইপ ইরেজার: যে কোনো মান পাস করা যেতে পারে, কিন্তু টাইপ হারিয়ে যায় ও কাস্টিং (as?) প্রয়োজন।

কিভাবে একটি প্রোটোকলের সাথে Generic সীমাবদ্ধ করবেন?

কোণাকার ব্র্যাকেটে T: SomeProtocol সিনট্যাক্স বা একটি পৃথক ক্লজ় where T: SomeProtocol ব্যবহার করুন। সীমাবদ্ধি নিশ্চিত করে যে generic প্যারামিটার নির্দিষ্ট পদ্ধতি ও বৈশিষ্ট্য সমর্থন করে।

একটি প্রোটোকলে Associated Type কি?

Associated Type (associatedtype) একটি প্রোটোকলের ভিতরে একটি টাইপের জন্য একটি প্লেসহোল্ডার। প্রোটোকল একটি নির্দিষ্ট টাইপ নির্দিষ্ট করে না বরং একটি associatedtype ঘোষণা করে, যা বাস্তবায়নে নির্দিষ্ট হয়: Array এর Element, Dictionary এর Key ও Value।

Generic কি নির্দিষ্ট টাইপের চেয়ে দ্রুত বা ধীরে?

Swift generic কোডকে প্রতিটি নির্দিষ্ট টাইপের জন্য বিশেষায়ন সংস্করণ এ কম্পাইল করে। ব্যবহারিকভাবে, Int এর জন্য একটি generic ফাংশন Int এর জন্য হাতে লেখা ফাংশনের চেয়ে ধীরে নয়। অমূর্ততার কোনো ওভারহেড নেই।

সারাংশ

  • Generic — টাইপ প্যারামিটার সহ জেনারিক প্রোগ্রামিং প্রক্রিয়া
  • ফাংশন ও টাইপ generic প্যারামিটার সহ একাধিক ডপ্লিকেট বাস্তবায়ন প্রতিস্থাপন করে
  • where সীমাবদ্ধি generic কে প্রয়োজনীয় শর্তে সীমিত করে
  • Associated Types প্রোটোকলকে ঘোষণা সময় নির্দিষ্টকরণ ছাড়া জেনারিক হতে দেয়
  • এক্সটেনশন where সহ কেবল শর্ত পূরণ হলে কার্যকারিতা যোগ করে
  • কম্পাইলার বিশেষায়ন কোড উত্পাদন করে — generic কোনো ওভারহেড যোগ করে না
  • অতিরিক্ত প্যারামিটারাইজেশন একটি অনাতস্ব — কেবল যখন টাইপ প্রকৃতিভাবে ভিন্ন হয় তখন generic ব্যবহার করুন

আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব

IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।

প্রকল্প নিয়ে আলোচনা করুন

আরও পড়ুন