مرکزی مواد پر جائیں
ماڈیول 10 · سبق 3 از 5کورس میں 48/50~15 min
ماڈیول اسباق (3/5)

عمومیات (1.18+ پر جائیں)

Go 1.18 (مارچ 2022) کے بعد سے، قسم کے پیرامیٹرز دستیاب ہیں: فنکشنز اور اقسام کو اقسام پر پیرامیٹرائز کیا جا سکتا ہے۔ وہ آپ کو Map، Filter، Set[T]، LinkedList[T] کو ڈپلیکیٹ کوڈ کے بغیر اور interface{} + رن ٹائم قسم کے دعووں کے بغیر لکھنے دیتے ہیں۔

عام فعل: نحو

Go
func Map[T, U any](s []T, f func(T) U) []U {
    out := make([]U, len(s))
    for i, v := range s {
        out[i] = f(v)
    }
    return out
}

doubled := Map([]int{1, 2, 3}, func(n int) int { return n * 2 })
// doubled is []int{2, 4, 6}

تین نئے عناصر:

  • [T, U any] نام کے بعد: قسم کے پیرامیٹرز کا ان کی رکاوٹوں کے ساتھ اعلان کرتا ہے۔
  • any = رکاوٹ جو کسی بھی قسم کو قبول کرتی ہے (1.18 کے بعد سے interface{} کا عرف)۔
  • تخمینہ: Map([]int{...}, ...) کو کال کرنے کے لیے آپ کو Map[int, int](...) لکھنے کی ضرورت نہیں ہے: مرتب کرنے والا T=int, U=int کا اندازہ لگاتا ہے۔

بعض اوقات تخمینہ کافی نہیں ہوتا ہے (مثال کے طور پر، کنسٹرکٹرز بغیر T دلائل) اور واضح انسٹی ٹیشن کی ضرورت ہوتی ہے: New[*Server]()۔

بلٹ ان پابندیاں

پابندیمعنی
anyکوئی بھی قسم (== interface{})۔
comparable== اور != کے ساتھ قسمیں: عددی، سٹرنگ، بول، پوائنٹرز، چینلز، تقابلی صفیں/سٹرکٹس۔

comparable برابری کی اجازت دیتا ہے لیکن نہیں < یا >۔

Go
func Index[T comparable](s []T, x T) int {
    for i, v := range s {
        if v == x { return i }
    }
    return -1
}

</> کیلئے آپ کو حسب ضرورت پابندی کی ضرورت ہے۔

حسب ضرورت رکاوٹ: یونینز ٹائپ کریں۔

ایک رکاوٹ ایک انٹرفیس ہے جس میں "قسم عنصر" کی شقیں ہیں:

Go
type Ordered interface {
    ~int | ~int64 | ~float64 | ~string
}

func Min[T Ordered](a, b T) T {
    if a < b { return a }
    return b
}
  • | = یونین: درج کردہ اقسام میں سے کسی کو بھی قبول کرتا ہے۔
  • ~int = "int یا کسی بھی قسم کی وضاحت کی گئی ہے type X int" (اسی بنیادی قسم کے ساتھ)۔ ~ کے بغیر، صرف عین مطابق int۔

ایک رکاوٹ بھی طریقوں کو ملا سکتی ہے اور عناصر کو ٹائپ کر سکتی ہے:

Go
type Stringable interface {
    ~string
    Len() int
}

عام اقسام

نہ صرف افعال: سٹرکٹس اور انٹرفیس میں بھی قسم کے پیرامیٹرز ہوسکتے ہیں۔

Go
type Set[T comparable] struct {
    m map[T]struct{}
}

func NewSet[T comparable]() *Set[T] {
    return &Set[T]{m: make(map[T]struct{})}
}

func (s *Set[T]) Add(v T) { s.m[v] = struct{}{} }
func (s *Set[T]) Has(v T) bool { _, ok := s.m[v]; return ok }

s := NewSet[string]()
s.Add("ada")

طریقے قسم کے پیرامیٹرز کو اس قسم سے آگے نہیں جوڑ سکتے ہیں: func (s *Set[T]) MapTo[U any](...) مرتب نہیں کرتا (جان بوجھ کر ڈیزائن کی حد)۔

جنرک کب استعمال کریں۔

ہاں جب:

  • منطق کئی اقسام (مجموعے، الگورتھم، مددگار جیسے Map/Filter/Reduce) کے لیے واقعی ایک جیسی ہے۔
  • متبادل کوڈ کو ڈپلیکیٹ کرنا یا interface{} + قسم کے دعوے (قسم کی حفاظت کو کھونا) استعمال کرنا ہوگا۔

نہیں جب:

  • ایک یا دو طریقوں کے ساتھ ایک انٹرفیس کافی اور زیادہ پڑھنے کے قابل ہے (io.Reader, fmt.Stringer)۔
  • آپ پیرامیٹرائز کر رہے ہیں "کیونکہ آپ کر سکتے ہیں": ایک واحد استعمال کیس → اس کا ایک ٹھوس ورژن بنائیں۔

مشقیں

ورزش#go.m10.l3.e1
کوششیں: 0لوڈ ہو رہا ہے…

Definisci la funzione generica Min[T Ordered](a, b T) T che ritorna il minore usando l'operatore <. Il constraint حکم دیا è già fornito.

ایڈیٹر لوڈ ہو رہا ہے…

3 کوششوں کے بعد حل دستیاب ہے۔

ورزش#go.m10.l3.e2
کوششیں: 0لوڈ ہو رہا ہے…

نقشہ کو لاگو کریں

ایڈیٹر لوڈ ہو رہا ہے…

3 کوششوں کے بعد حل دستیاب ہے۔

Quiz#go.m10.l3.e3
تیار

Quale constraint بلٹ ان consente l'operatore == ma NON l'operatore <?

Go
func Index[T ???](s []T, x T) int { ... }
جواب کے اختیارات