اختبارات

defer 1

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


package main

type Foo struct {
	v int
}

func MakeFoo(n *int) Foo {
	print(*n)
	return Foo{}
}

func (Foo) Bar(n *int) {
	print(*n)
}

func main() {
	var x = 1
	var p = &x
	defer MakeFoo(p).Bar(p) // السطر 19
	x = 2
	p = new(int) // السطر 21
	MakeFoo(p)
}

الخيارات:

  • 100
  • 102
  • 022
  • 011

الإجابة: 102

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

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

  • عند دفع استدعاء دالة إلى قائمة الاستدعاءات المؤجَّلة، تُقيَّم قيمة الدالة المُستدعاة وجميع المعطيات. وستُستخدم القيم المُقيَّمة عند تنفيذ الاستدعاء لاحقاً في مرحلة خروج دالة المستدعي.
  • لذا، عند السطر 19، عند دفع الاستدعاء المؤجَّل Bar إلى قائمة الاستدعاءات المؤجَّلة، تُقيَّم معطياته MakeFoo(p) (كمعطى المستقبِل) وp. وعند تقييم MakeFoo(p) تُطبع القيمة 1.
  • لا يؤثر التعديل اللاحق عند السطر 21 على نتائج التقييم عند السطر 19، ما يعني أن المعطى المُمرَّر إلى استدعاء الدالة Bar لا يزال مؤشراً إلى المتغير x.

اختبار مشابه:


package main

type T int

func (t T) M(n int) T {
	print(n)
	return t
}

func main() {
	var t T
	defer t.M(1).M(2)
	t.M(3).M(4)
}

يطبع برنامج الاختبار أعلاه 1342.