اختبارات

defer 2

ماذا يطبع البرنامج التالي؟


package main

func bar() (r int) {
	defer func() {
		r += 4
		if recover() != nil {
			r += 8
		}
	}()

	var f func()
	defer f()
	f = func() {
		r += 2
	}

	return 1
}

func main() {
	println(bar())
}

الخيارات:

  • 1
  • 7
  • 12
  • 13

الإجابة: 13

شغِّله على Go play.

النقاط الأساسية:

  • السطر 12: عند دفع الاستدعاء f() إلى قائمة الاستدعاءات المؤجَّلة، تُقيَّم f على أنها nil. واستدعاء دالة nil يُنتج panic. لكن الـ panic لا يحدث في وقت الدفع، بل سيحدث في وقت التنفيذ لاحقاً خلال مرحلة الخروج من استدعاء الدالة bar().
  • السطر 13-15: ليس للإسناد إلى f أي أثر على نتيجة التنفيذ. بعبارة أخرى، هذا الإسناد عديم الفائدة فعلياً.
  • السطر 4-9: يمكن للاستدعاء المؤجَّل أن يعدّل نتيجة الإرجاع المُسمَّاة للدالة الحاوية له (هنا الدالة bar).