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 کی بنیاد ہیں۔

Generics کی ضرورت کیوں

Generics کے بغیر، آپ کو ہر ٹائپ کے لیے علیحدہ فنکشنز لکھنے ہونگے: 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 کے بغیر آپ value کو dictValue سے موازنہ نہیں کر سکتے۔

where کے ذریعے ٹائپ پابندیاں

where — Swift کا ایک کلمہ کلیدی ہے جو generic پارامیٹرز پر اضافی پابندیاں عائد کرتا ہے۔ زاویے بریکٹس () میں صرف ایک پروٹیکل متعین کرنے کے برعکس، where مزید پیچیدہ شرائط کو ظاہر کرنے کی اجازت دیتا ہے: متعدد پروٹیکلز کی تعمیل، ٹائپ پارامیٹرز کے درمیان تعلقات، اور associated types کی تطویر۔

where کا سنٹیکس

where کا جملہ فنکشن یا ٹائپ کے دستخت کے بعد، کھولے ہونے والے تیرے سے پہلے لکھا جاتا ہے۔ where میں آپ متعین کر سکتے ہیں کہ T: Comparable & Hashable (ایک ساتھ دو پروٹیکلز کی تعمیل) یا T.U == Int (ایک associated type کو ٹھوس کرنا)۔

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 where T: SomeProtocol استعمال کریں۔ پابندیاں اس بات کی ضمانت دیتی ہیں کہ generic پارامیٹر مخصوص میتھڈز اور خوصیات کو سپورٹ کرتا ہے۔

ایک پروٹیکل میں Associated Type کیا ہے؟

Associated Type (associatedtype) ایک پروٹیکل کے اندر ایک ٹائپ کے لیے ایک پلیس ہولڈر ہے۔ پروٹیکل ایک ٹھوس ٹائپ متعین نہیں کرتا بلکھ ایک associatedtype کا اعلان کرتا ہے، جو نفاذ میں ٹھوس ہوتا ہے: Array کا Element، Dictionary کا Key اور Value۔

کیا Generics ٹھوس ٹائپس سے تیز یا آہسٹے ہیں؟

Swift generic کوڈ کو ہر ٹھوس ٹائپ کے لیے مخصوصی ورشنز میں کامپائل کرتا ہے۔ عملی طور پر، Int کے لیے ایک generic فنکشن Int کے لیے هاتھ سے لکھے گئے فنکشن سے آہستہ نہیں ہے۔ تجرید کا کوئی اورہیڈ نہیں ہے۔

خلاصہ

  • Generic — ٹائپ پارامیٹر کے ساتھ جنریک پروگرامنگ میکانزم
  • فنکشنز اور اقسام generic پارامیٹرز کے ساتھ متعدد دوہرائے گئے نفاذوں کو بدلتے ہیں
  • where پابندیاں generic کی گونڈائی کو ضروری شرائط تک محدود کرتی ہیں
  • Associated Types پروٹیکلز کو اعلان پر ٹھوس کیئے بغیر جنریک بننے دیتے ہیں
  • ایکسٹنشنز where کے ساتھ صرف شرائط پوری ہونے پر فنکشنالٹی شامل کرتے ہیں
  • کامپائلر مخصوصی کوڈ تیار کرتا ہے — generic کوئی اورہیڈ نہیں ڈالتا
  • ضرورت سے زیادہ پارامیٹرائزیشن ایک انٹی پیٹرن ہے — generic کو صرف تب استعمال کریں جب ٹائپ واقعی متغیر ہو

ہم ایک موبائل ایپلیکیشن ٹرنکی تیار کریں گے

IT Sectr 2017 سے اسٹارٹ اپس اور کاروبار کے لیے iOS اور Android ایپلیکیشنز بناتا ہے۔ ہم آپ کو مشورہ دیں گے اور بہترین حل تجویز کریں گے۔

پروجیکٹ پر بحث کریں

مزید پڑھیں