دروس الوحدة (2/5)
نوع التأكيد
تأكيد النوع يستخرج النوع الملموس من قيمة الواجهة.
أنت في حاجة إليها عندما يكون لديك interface{} (أو واجهة "عالية") في
اليد وتحتاج إلى التعامل معها كنوع محدد للوصول إلى الحقول أو
الأساليب غير موجودة على الواجهة.
بناء الجملة
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شكلان ودلالتان:
| النموذج | النجاح | فشل |
|---|---|---|
| محمي_INLINE_6 | v = قيمة النوع T | ** الذعر ** في وقت التشغيل |
| محمي_INLINE_8 | محمي_INLINE_9, محمي_INLINE_10 | v = القيمة الصفرية لـ T، ok=false |
نموذج "Comma ok": الأكثر أمانًا
var i interface{} = 42
if s, ok := i.(string); ok {
fmt.Println("è stringa:", s)
} else {
fmt.Println("non è stringa, ignoro")
}يتيح لك ok التعامل مع حالة "النوع الخاطئ" دون ذعر. انها
النمط الاصطلاحي في الغالبية العظمى من الحالات.
التأكيد على الواجهة
لا ينطبق التأكيد على الأنواع الملموسة فقط، بل على أنواع أخرى أيضًا واجهات:
type Closer interface { Close() error }
func tryClose(x interface{}) {
if c, ok := x.(Closer); ok {
c.Close()
}
}نمط شائع جدًا في المكتبة القياسية: "إذا كانت مدخلاتي أيضًا
io.Closer، اتصل بالإغلاق في النهاية".
التأكيد على المؤشرات مقابل القيم
يجب أن يتطابق التأكيد مع النوع الديناميكي تمامًا:
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 هما نوعان متميزان لنظام الكتابة.
متى يتم استخدام التأكيد مقابل مفتاح النوع
- نوع واحد محتمل فقط، التحقق من "الكشف عن الميزات" (على سبيل المثال الإرسال إلى واجهة اختيارية): تأكيد النوع مع
comma ok. - 2+ أنواع محتملة، الإرسال عبر فروع متعددة: نوع التبديل (الدرس التالي).
جربه
استخدم نمط الفاصلة موافق لاستخراج سلسلة من i.
إظهار التلميح
بناء الجملة: `v، ok := i.(T)`.
الحل متاح بعد 3 من المحاولات
اكتب التأكيد على int بدون فاصلة ok (بافتراض أنني يحتوي على int).
إظهار التلميح
بدون `ok` تفترض أن النوع مؤكد؛ خلاف ذلك الذعر.
الحل متاح بعد 3 من المحاولات
ماذا يحدث مع `s := i.(string)` إذا كنت تحتوي على int؟
var i interface{} = 42
s := i.(string)خلاصة
v := i.(T): الذعر إذا كان النوع الديناميكي ≠ T.v, ok := i.(T): النمط الآمن، حددok.- يعمل أيضًا ضد واجهة أخرى ("كشف الميزة").
Tو*Tهما نوعان متميزان للتأكيد.- نوع واحد → التأكيد؛ 2+ أنواع → نوع التبديل.