ماڈیول اسباق (3/5)
عمومیات (1.18+ پر جائیں)
Go 1.18 (مارچ 2022) کے بعد سے، قسم کے پیرامیٹرز دستیاب ہیں: فنکشنز اور اقسام کو اقسام پر پیرامیٹرائز کیا جا سکتا ہے۔ وہ آپ کو Map، Filter، Set[T]، LinkedList[T] کو ڈپلیکیٹ کوڈ کے بغیر اور interface{} + رن ٹائم قسم کے دعووں کے بغیر لکھنے دیتے ہیں۔
عام فعل: نحو
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 برابری کی اجازت دیتا ہے لیکن نہیں < یا >۔
func Index[T comparable](s []T, x T) int {
for i, v := range s {
if v == x { return i }
}
return -1
}</> کیلئے آپ کو حسب ضرورت پابندی کی ضرورت ہے۔
حسب ضرورت رکاوٹ: یونینز ٹائپ کریں۔
ایک رکاوٹ ایک انٹرفیس ہے جس میں "قسم عنصر" کی شقیں ہیں:
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۔
ایک رکاوٹ بھی طریقوں کو ملا سکتی ہے اور عناصر کو ٹائپ کر سکتی ہے:
type Stringable interface {
~string
Len() int
}عام اقسام
نہ صرف افعال: سٹرکٹس اور انٹرفیس میں بھی قسم کے پیرامیٹرز ہوسکتے ہیں۔
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)۔ - آپ پیرامیٹرائز کر رہے ہیں "کیونکہ آپ کر سکتے ہیں": ایک واحد استعمال کیس → اس کا ایک ٹھوس ورژن بنائیں۔
مشقیں
Definisci la funzione generica Min[T Ordered](a, b T) T che ritorna il minore usando l'operatore <. Il constraint حکم دیا è già fornito.
3 کوششوں کے بعد حل دستیاب ہے۔
نقشہ کو لاگو کریں
3 کوششوں کے بعد حل دستیاب ہے۔
Quale constraint بلٹ ان consente l'operatore == ma NON l'operatore <?
func Index[T ???](s []T, x T) int { ... }