मुख्य सामग्री पर जाएं
मॉड्यूल 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) (एक मान) के साथ, गो T के विधि सेट को देखता है, यह नहीं मिलता है, और डिफ़ॉल्ट प्रारूप का उपयोग करता है। इससे बचने के लिए, मूल्य रिसीवर का उपयोग आमतौर पर String() के लिए किया जाता है (यह एक "दृश्य" है; ऐसा नहीं है) कुछ भी संशोधित करें)।

इसे अजमाएं

व्यायाम#go.m6.l4.e1
प्रयास: 0लोड हो रहा है...

प्वाइंट पर स्ट्रिंग() लागू करें ताकि यह (एक्स, वाई) लौटाए।

संपादक लोड हो रहा है...
संकेत दिखाएँ

फ़ील्ड्स को फ़ॉर्मेट करने के लिए `fmt.Sprintf` का उपयोग करें।

3 प्रयासों के बाद समाधान उपलब्ध है

व्यायाम#go.m6.l4.e2
प्रयास: 0लोड हो रहा है...

स्ट्रिंग() को एक प्रकार की स्थिति (int) पर लागू करें: 0 → 'ठीक', 1 → 'चेतावनी', अन्यथा → 'ERR'।

संपादक लोड हो रहा है...
संकेत दिखाएँ

रिसीवर के मूल्य पर स्विच करें; डिफ़ॉल्ट प्रदान करना याद रखें.

3 प्रयासों के बाद समाधान उपलब्ध है

Quiz#go.m6.l4.e3
तैयार

fmt.Stringer को संतुष्ट करने के लिए विधि में कौन सा हस्ताक्षर होना चाहिए?

Go
func (x T) ??? {}
उत्तर विकल्प

संक्षिप्त

  • fmt.Stringer = interface { String() string }.
  • इसे लागू करने से fmt.Print* प्रकार का प्रतिनिधित्व करने का तरीका बदल जाता है।
  • एनम्स (iota), डोमेन प्रकार, कोड/पहचानकर्ता के लिए मुहावरेदार।
  • कभी भी fmt.Sprintf("%s", t) को t के अंदर String() (पुनरावृत्ति) पर कॉल न करें।
  • कन्वेंशन: String() के लिए मूल्य रिसीवर (कोई उत्परिवर्तन नहीं, "विधि-निर्धारित आश्चर्य" से बचा जाता है)।