דילוג לתוכן המרכזי
מודול 6 · שיעור 2 מתוך 527/50 בקורס~10 min
שיעורי מודול (2/5)

סוג קביעה

הצהרת סוג מחלצת את הסוג הקונקרטי מערך ממשק. אתה צריך את זה כשיש לך interface{} (או ממשק "גבוה") ב יד וצריך להתייחס אליה כאל הסוג הספציפי שלה כדי לגשת לשדות או שיטות שאינן קיימות בממשק.

תַחבִּיר

Go
var i interface{} = "ciao"

s := i.(string)           // "panic" form: panics if it's not a string
s, ok := i.(string)       // "comma ok" form: ok = false if it's not a string

שתי צורות, שתי סמנטיות:

טופסהצלחהכישלון
v := i.(T)v = ערך מסוג Tבהלה בזמן ריצה
v, ok := i.(T)v=..., ok=truev = ערך אפס של T, ok=false

טופס "פסיק בסדר": הכי בטוח

Go
var i interface{} = 42

if s, ok := i.(string); ok {
    fmt.Println("è stringa:", s)
} else {
    fmt.Println("non è stringa, ignoro")
}

ok מאפשר לך לטפל במקרה של "סוג לא נכון" ללא פאניקה. זה ה דפוס אידיומטי ברוב המכריע של המקרים.

טענה לממשק

הטענה לא עובדת רק על סוגי קונקרטיים, אלא גם על אחרים ממשקים:

Go
type Closer interface { Close() error }

func tryClose(x interface{}) {
    if c, ok := x.(Closer); ok {
        c.Close()
    }
}

דפוס נפוץ מאוד בספרייה הסטנדרטית: "אם הקלט שלי הוא גם an io.Closer, התקשר לסגור בסוף".

טענה על מצביעים מול ערכים

הטענה חייבת להתאים בדיוק לסוג הדינמי:

Go
type Cat struct{}
func (c *Cat) Meow() {}

var a interface{} = &Cat{}

c1, ok := a.(*Cat)   // ok = true
c2, ok := a.(Cat)    // ok = false: it holds *Cat, not Cat

*Cat וCat הם סוגים נפרדים עבור מערכת הסוג.

מתי להשתמש ב-assertion vs type switch

  • סוג אחד אפשרי בלבד, בדיקת "זיהוי תכונה" (למשל, העברה לממשק אופציונלי): הצהרת סוג עם comma ok.
  • 2+ סוגים אפשריים, שיגור על פני מספר סניפים: מתג סוג (השיעור הבא).

נסה את זה

פעילות גופנית#go.m6.l2.e1
ניסיונות: 0טוען...

השתמש בדוגמת פסיק אישור כדי לחלץ מחרוזת מ-i.

טוען עורך...
הצג רמז

תחביר: `v, ok := i.(T)`.

הפתרון זמין לאחר 3 ניסיונות

פעילות גופנית#go.m6.l2.e2
ניסיונות: 0טוען...

הקלד assertion ל-int ללא פסיק ok (נניח ש-i מכיל int).

טוען עורך...
הצג רמז

בלי `בסדר` אתה מניח שהסוג בטוח; אחרת פאניקה.

הפתרון זמין לאחר 3 ניסיונות

Quiz#go.m6.l2.e3
מוכן

מה קורה עם `s := i.(string)` אם i מכיל int?

Go
var i interface{} = 42
s := i.(string)
אפשרויות תשובה

לְסַכֵּם

  • v := i.(T): פאניקה אם הסוג הדינמי ≠ T.
  • v, ok := i.(T): דפוס בטוח, סמן את ok.
  • עובד גם נגד ממשק אחר ("זיהוי תכונה").
  • T ו-*T הם סוגים נפרדים עבור הטענה.
  • סוג אחד → קביעה; 2+ סוגים → מתג סוג.