แลมบ์ดา (หรือปิด ) ห่อหุ้มทั้งตัวชี้ฟังก์ชันและตัวแปร นี่คือเหตุผลที่ใน C # คุณสามารถทำได้:
int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
return i < lessThan;
};
ฉันใช้ตัวแทนที่ไม่ระบุชื่อที่นั่นเป็นการปิด (ไวยากรณ์จะชัดเจนและใกล้เคียงกับ C เล็กน้อยกว่าแลมบ์ดาเทียบเท่า) ซึ่งจับ lessThan (ตัวแปรสแต็ก) ในการปิด เมื่อมีการประเมินการปิด lessThan (ซึ่งสแต็กเฟรมอาจถูกทำลาย) จะยังคงถูกอ้างอิงต่อไป ถ้าฉันเปลี่ยนน้อยกว่าฉันก็เปลี่ยนการเปรียบเทียบ:
int lessThan = 100;
Func<int, bool> lessThanTest = delegate(int i) {
return i < lessThan;
};
lessThanTest(99);
lessThan = 10;
lessThanTest(99);
ใน C สิ่งนี้จะผิดกฎหมาย:
BOOL (*lessThanTest)(int);
int lessThan = 100;
lessThanTest = &LessThan;
BOOL LessThan(int i) {
return i < lessThan;
}
แม้ว่าฉันสามารถกำหนดตัวชี้ฟังก์ชันที่รับ 2 อาร์กิวเมนต์:
int lessThan = 100;
BOOL (*lessThanTest)(int, int);
lessThanTest = &LessThan;
lessThanTest(99, lessThan);
lessThan = 10;
lessThanTest(100, lessThan);
BOOL LessThan(int i, int lessThan) {
return i < lessThan;
}
แต่ตอนนี้ฉันต้องผ่าน 2 ข้อโต้แย้งเมื่อฉันประเมินมัน ถ้าฉันต้องการส่งตัวชี้ฟังก์ชันนี้ไปยังฟังก์ชันอื่นที่ lessThan ไม่ได้อยู่ในขอบเขตฉันอาจจะต้องทำให้มันมีชีวิตอยู่ด้วยตนเองโดยส่งผ่านไปยังแต่ละฟังก์ชันในห่วงโซ่หรือโดยการเลื่อนระดับไปทั่วโลก
แม้ว่าภาษากระแสหลักส่วนใหญ่ที่รองรับการปิดจะใช้ฟังก์ชันที่ไม่ระบุตัวตน แต่ก็ไม่มีข้อกำหนดสำหรับสิ่งนั้น คุณสามารถปิดได้โดยไม่ต้องใช้ฟังก์ชันที่ไม่ระบุตัวตนและฟังก์ชันที่ไม่ระบุชื่อโดยไม่ต้องปิด
สรุป: การปิดเป็นการรวมกันของตัวชี้ฟังก์ชัน + ตัวแปรที่จับได้