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

سٹرنگر انٹرفیس

fmt.Stringer شاید سب سے زیادہ استعمال ہونے والا معیاری انٹرفیس ہے۔ گو کی معیاری لائبریری۔ یہ طاقت کا بہترین مظاہرہ ہے۔ چھوٹے انٹرفیس کے.

تعریف

Go
type Stringer interface {
    String() string
}

ایک ہی دستخط۔ کوئی بھی قسم جو String() string کی وضاحت کرتی ہے مطمئن کرتی ہے۔ یہ اور fmt اس انٹرفیس کو پہچانتا ہے: جب آپ کوئی قدر پاس کرتے ہیں۔ fmt.Print*، اگر یہ Stringer کو لاگو کرتا ہے، تو String() کا نتیجہ پہلے سے طے شدہ نمائندگی کے بجائے استعمال کیا جاتا ہے۔

مثال

Go
type Point struct{ X, Y int }

func (p Point) String() string {
    return fmt.Sprintf("(%d,%d)", p.X, p.Y)
}

fmt.Println(Point{1, 2})              // (1,2)
fmt.Printf("%v %s\n", Point{3, 4}, Point{5, 6})
// (3,4) (5,6)

%v، %s، Println میں حسب ضرورت فارمیٹنگ کے ساتھ وہی قدر پرنٹ کرتی ہے Sprint، log، وغیرہ۔ سب صرف ایک طریقہ کی وضاحت کر کے۔

جب یہ سمجھ میں آتا ہے۔

  • وہ قسمیں جو ڈومین کو ماڈل کرتی ہیں (آئی ڈی، کوڈز، کوآرڈینیٹ، شماریات)۔
  • انسانی پڑھنے کے قابل نمائندگی کے ساتھ غلطیاں (error پر اگلا سبق دیکھیں)۔
  • وہ قسمیں جو آپ اکثر لاگ ان کرتے ہیں اور جن کے لیے آپ ایک مقررہ فارمیٹ چاہتے ہیں۔

ہر چیز کے لیے نہیں: اگر قسم سادہ ہے اور پہلے سے طے شدہ نمائندگی ٹھیک ہے، شور مت ڈالو۔

اینوم کی اقسام: iota کے ساتھ عام پیٹرن

Go
type Status int

const (
    OK Status = iota
    WARN
    ERR
)

func (s Status) String() string {
    switch s {
    case OK:   return "OK"
    case WARN: return "WARN"
    case ERR:  return "ERR"
    default:   return "UNKNOWN"
    }
}

fmt.Println(OK, WARN, ERR)   // OK WARN ERR

String() کے بغیر، fmt.Println(OK) پرنٹ کرے گا 0۔ String() کے ساتھ، یہ علامتی نام پرنٹ کرتا ہے۔ stringer ٹول خود بخود اس پیٹرن کو تیار کرتا ہے۔

لامحدود تکرار پر نگاہ رکھیں

Go
type T int
func (t T) String() string {
    return fmt.Sprintf("%d", int(t))  // OK: cast to int breaks the recursion
}

پوائنٹر ریسیور پر سٹرنگر

اگر String() کے پاس پوائنٹر وصول کنندہ ہے، تو صرف *T مطمئن کرتا ہے Stringer۔ fmt.Println(t) (ایک قدر) کے ساتھ، Go T کے طریقہ کار کو دیکھتا ہے، اسے نہیں ملتا، اور ڈیفالٹ فارمیٹ استعمال کرتا ہے۔ اس سے بچنے کے لیے، ** قدر وصول کنندہ** عام طور پر String() کے لیے استعمال ہوتا ہے (یہ ایک "دیکھا" ہے؛ ایسا نہیں ہوتا کسی بھی چیز میں ترمیم کریں)۔

اسے آزمائیں

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

String() کو پوائنٹ پر لاگو کریں تاکہ یہ (X,Y) واپس آجائے۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

فیلڈز کو فارمیٹ کرنے کے لیے `fmt.Sprintf` استعمال کریں۔

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

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

سٹرنگ () کو ایک قسم کی حالت (int) پر لاگو کریں: 0 → 'OK'، 1 → 'WARN'، بصورت دیگر → 'ERR'۔

ایڈیٹر لوڈ ہو رہا ہے…
اشارہ دکھائیں۔

وصول کنندہ کی قدر کو آن کریں؛ ڈیفالٹ فراہم کرنا یاد رکھیں۔

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

Quiz#go.m6.l4.e3
تیار

fmt.Stringer کو مطمئن کرنے کے لیے کون سا دستخط ہونا چاہیے؟

Go
func (x T) ??? {}
جواب کے اختیارات

Recap

  • fmt.Stringer = interface { String() string }
  • اسے نافذ کرنے سے fmt.Print* قسم کی نمائندگی کرنے کا طریقہ بدل جاتا ہے۔
  • enums (iota)، ڈومین کی اقسام، کوڈز/شناخت کنندگان کے لیے محاورہ۔
  • کبھی بھی fmt.Sprintf("%s", t) پر t کے اندر String() (دوبارہ) پر کال نہ کریں۔
  • کنونشن: String() کے لیے قدر وصول کنندہ (کوئی تغیر نہیں، "طریقہ کار کی حیرت انگیزیوں" سے گریز کرتا ہے)۔