✨Bao đóng (lập trình máy tính)

Bao đóng (lập trình máy tính)

Trong khoa học máy tính, bao đóng (closure) là một hàm hay một tham chiếu tới một hàm cùng với môi trường tham chiếu - một bảng chứa tham chiếu đến mỗi biến không phải cục bộ (hay còn gọi là biến tự do). Closure còn được gọi với tên là lexical closure (bao đóng hay function closure (bao đóng hàm). Bao đóng khác với một con trỏ hàm thuần túy ở chỗ nó cho phép một hàm có thể truy cập các biến không phải cục bộ ngay cả khi hàm này được gọi ngoài phạm vi của nó.

Ví dụ

Đoạn mã Python dưới đây định nghĩa một hàm counter với một biến cục bộ x và một hàm lồng (nested function) increment

def counter(): x = 0 def increment(y): nonlocal x x += y print(x) return increment Bao đóng được trả lại bởi counter có thể được gán cho một biến: counter1_increment = counter() counter2_increment = counter() Khi chúng ta gọi hàm increment thông qua bao đóng sẽ nhận được kết quả như sau: counter1_increment(1) # in ra kết quả 1 counter1_increment(7) # in ra kết quả 8 counter2_increment(1) # in ra kết quả 1 counter1_increment(1) # in ra kết quả 9

Sự khác biệt về ngữ cảnh

Phạm vi tác dụng

Các ngôn ngữ lập trình khác nhau không phải lúc nào cũng thống nhất về lexical environment(tạm dịch: phạm vi tác dụng) và định nghĩa về bao đóng trong các ngôn ngữ vì thế cũng có thể khác nhau. Định nghĩa đơn giản nhất của lexical environment chỉ ra một tập các binding của các biến trong một phạm vi nào đó. Đó cũng chính là điều bao đóng muốn lưu giữ (capture) lại. Ý nghĩa binding (tạm dịch: gắn kết) trong các ngôn ngữ cũng khác nhau. Trong các ngôn ngữ mệnh lệnh (imperative languages) các biến được gắn kết đến các vùng bộ nhớ lưu trữ giá trị của các biến đó. Việc lưu giữ lại các biến kiểu này được gọi là lưu giữ bằng tham chiếu (capturing by reference). Đoạn mã sau miêu tả một ví dụ trong ECMAScript

// ECMAScript var f, g; function foo() { var x = 0; f = function() { return ++x; }; g = function() { return --x; }; x = 1; alert('Bên trong foo, gọi hàm f(): ' + f()); // hiện ra giá trị "2" } foo(); alert('Gọi hàm g(): ' + g()); // hiện ra giá trị "1" alert('Gọi hàm f(): ' + f()); // hiện ra giá trị "2"

Trong ví dụ trên hàm foo và các bao đóng được tham chiếu bởi các biến f và biến g đều sử dụng chung một vùng bộ nhớ khi truy cập biến x. Chính vì vậy giá trị của x đều thay đổi sau mỗi lần gọi hàm foo hay gọi các hàm qua các bao đóng f và biến g

Trong khi đó rất nhiều các ngôn ngữ lập trình khác, ví dụ như ngôn ngữ ML, việc gắn kết biến lại đi liền trực tiếp với giá trị của biến. Kiểu lưu giữ này được gọi là lưu giữ bằng giá trị (capturing by value)

Một số ngôn ngữ cho phép chúng ta lựa chọn kiểu lưu trữ theo ý muốn. Ví dụ trong ngôn ngữ C++11 hay PHP, chúng ta sử dụng từ khóa & để lưu trữ biến theo tham chiếu. Khi không dùng từ khóa đó, các biến sẽ được lưu trữ theo giá trị.

Thoát khỏi phạm vi tác dụng

Các ngôn ngữ lập trình khác nhau cũng có sự khác nhau trong việc thoát khỏi phạm vi tác dụng xác định bởi các lệnh của ngôn ngữ đó, ví dụ: return, break hay continue. Ví dụ sau chỉ ra sự khác biệt trong hai ngôn ngữ Smalltalk và ECMAScript:

"Smalltalk" foo | xs | xs:= #(1 2 3 4). xs do: [:x | ^x]. ^0 bar Transcript show: (self foo printString) "in ra kết quả 1" // ECMAScript function foo() { var xs = [1, 2, 3, 4]; xs.forEach(function (x) { return x; }); return 0; } alert(foo()); // in ra kết quả 0

Các đoạn mã trên sẽ cho ra các kết quả khác nhau vì toán tử ^ của Smalltalk thực thi khác với toán tử return trong EMCAScript. Toán tử return trong EMCAScript sẽ thoát ra khỏi bao đóng phía trong và bắt đầu một vòng lặp mới của vòng lặp forEach trong khi toán tử ^ thực thi trên biến x (lệnh ^x sẽ kết thúc vòng lặp do và trả lại chương trình từ hàm foo.

👁️ 2 | 🔗 | 💖 | ✨ | 🌍 | ⌚
**Lập trình máy tính** hay **lập chương trình máy tính,** thường gọi tắt là **lập trình** (, hay _programming_), là việc lập ra chương trình làm việc cho máy có bộ xử lý, nói riêng
Trong khoa học máy tính, **bao đóng** (closure) là một hàm hay một tham chiếu tới một hàm cùng với môi trường tham chiếu - một bảng chứa tham chiếu đến mỗi biến không phải
nhỏ| Chương trình máy tính "Xin chào, thế giới" của [[Brian Kernighan (1978) ]] **Chương trình máy tính** là tập hợp các câu lệnh thực hiện một tác vụ cụ thể khi được máy tính
nhỏ|phải|A [[Graphical user interface|GUI Chương trình "Hello World", viết bằng ngôn ngữ Perl]] nhỏ|phải|Có thể thực thi dòng mã ở máy điện tử cầm tay [[PlayStation Portable homebrew|PlayStation Portable Sony.]] nhỏ|phải|Thử máy [[CNC ở Perspex]]
Trong lập trình hướng đối tượng, **lớp** (**class**) là một chương trình-mã-khuôn mẫu có thể mở rộng được để tạo các đối tượng, cung cấp giá trị khởi tạo cho trạng thái (biến thành viên)
Programming Paradigm hay **Phương thức lập trình** là một kiểu cơ bản của lập trình vi tính (Computer Programming). Paragigm với các khái niệm và sự trừu tượng dùng trong mô tả các thành phần
Trong lập trình hướng đối tượng, **hàm hủy** (tiếng Anh: _destructor_, viết tắt: _dtor_) là một phương thức được gọi tự động để hủy bỏ một đối tượng. Điều này xảy ra khi thời gian
phải|nhỏ|402x402px|[[Mã nguồn của một chương trình máy tính đơn giản được viết bằng ngôn ngữ lập trình C. Khi được biên dịch và chạy, nó sẽ cho kết quả "Hello, world!".]] **Ngôn ngữ lập trình**
thumb|Minh họa mã nguồn [[Java (programming language)|Java với comment **mở đầu** được biểu thị bằng màu **đỏ** và comment **nội dòng** bằng màu **lục**. **Mã chương trình** là bằng màu **lam**.]]Trong lập
Trong lập trình máy tính, một **triển khai của ngôn ngữ lập trình** là một hệ thống để thực thi chương trình máy tính. Có hai cách tiếp cận chung để triển khai một ngôn
Trong lập trình, **tham số** là biến được thu nhận bởi một chương trình con. Tại thời gian chạy, chương trình con sử dụng các giá trị được gán cho các tham số để thay
**Hacker** là người hiểu rõ hoạt động của hệ thống máy tính, mạng máy tính, có thể viết hay chỉnh sửa phần mềm, phần cứng máy tính để làm thay đổi, chỉnh sửa nó với
[[Phần cứng|Phần cứng máy tính là nền tảng cho xử lý thông tin (sơ đồ khối). ]] **Lịch sử phần cứng máy tính** bao quát lịch sử của phần cứng máy tính, kiến trúc của
**Pascal** là một ngôn ngữ lập trình cho máy tính thuộc dạng mệnh lệnh và thủ tục, được Niklaus Wirth phát triển vào năm 1970. Pascal là ngôn ngữ lập trình đặc biệt thích hợp
Khoa học máy tính nghiên cứu các cơ sở lý thuyết của thông tin và tính toán, cùng với các kỹ thuật thực tiễn để thực hiện và
thumb|right|upright=1.2|Trẻ em được dạy cách sử dụng máy tính xách tay cá nhân; màn hình CRT, bàn phím và chuột máy tính để bàn cũ hơn (thời 1990) có thể nhìn thấy trong nền. **Máy
thumb|**[[Phép tính lambda** là một hệ thống hình thức để định nghĩa hàm, ứng dụng hàm và đệ quy được Alonzo Church đề xuất vào những năm 193x.]] **Lý thuyết ngôn ngữ lập trình** (thường
nhỏ|220x220px| Trẻ em chơi _[[Paperboy (trò chơi điện tử)|Paperboy_ trên CPC Amstrad 464 vào năm 1988 ]] nhỏ|220x220px| Hầu hết các máy tính gia đình, như Máy tính màu Tandy 3 này, bao gồm một
Trong lập trình máy tính, **tầm vực** (tiếng Anh: _scope_) của một ràng buộc tên – liên kết tên với một thực thể, ví dụ như biến – là một vùng của chương trình máy
**Bảo tàng Lịch sử Máy tính và Công nghệ Thông tin** (tiếng Ba Lan: _Muzeum Historii Komputerów i Informatyki_) là một bảo tàng tọa lạc tại số 2 Quảng trường Quốc hội Silesian, Katowice, Ba
Trong điện toán và truyền thông, **payload** là phần dữ liệu thực sự được truyền đi của một gói tin giữa hai phía, mà không chứa dữ liệu giao thức hay siêu dữ liệu -
phải|nhỏ|277x277px| Minh họa của một ứng dụng sử dụng libvorbisfile để phát file Ogg Vorbis Trong khoa học máy tính, **thư viện** là tập hợp các tài nguyên không biến động được sử dụng bởi
nhỏ|phải|243x243px|Ảnh chụp giao diện [[phần mềm diệt virus có tên FireLion- FastHelper]] Trong khoa học máy tính viễn thông, **virus máy tính** hay **virus tin học** (thường được người sử dụng gọi tắt là **virus**)
**Lập trình hướng đối tượng** () là một mẫu hình lập trình dựa trên khái niệm "đối tượng", mà trong đó, đối tượng chứa đựng các dữ liệu trong các trường, thường được gọi là
**PC game** còn gọi là **trò chơi máy tính**, là thể loại trò chơi video được chơi trên các máy tính cá nhân (PC), thay vì chơi trên máy chơi trò chơi điện tử tại
Biểu trưng chính thức nhỏ|250x250px|Một biển báo điện tử hiển thị ngày 3 tháng 1 năm 1900 vào ngày 3 tháng 1 năm 2000 ở [[Pháp.]] **Sự cố máy tính năm 2000** (còn được gọi
**John McCarthy** (4 tháng 9 năm 1927 - 24 tháng 10 năm 2011) là một nhà khoa học máy tính và nhà khoa học nhận thức người Mỹ. McCarthy là một trong những người sáng
nhỏ|300x300px| [[Petr Mitrichev (trái) và Gennady Korotkevich (phải), hai lập trình viên thi đấu nổi tiếng trong một cuộc thi.]] **Lập trình thi đấu** () là một môn thể thao trí tuệ trong đó những
phải|nhỏ|325x325px|[[Kết xuất hex của sâu Blaster, hiển thị một thông điệp lập trình viên sâu này để lại cho Giám đốc điều hành Microsoft Bill Gates]] nhỏ|325x325px|Sự lây lan của [[Conficker|sâu Conficker]] **Sâu máy tính**
nhỏ|Một chiếc laptop [[Lenovo "thời hiện đại"]] **Máy tính xách tay** hay **máy vi tính xách tay** (Tiếng Anh: **laptop computer** hay **laptop PC**) là một chiếc máy tính cá nhân nhỏ gọn có thể
Đây là danh sách các ngôn ngữ lập trình đáng chú ý, được nhóm theo loại. Vì không có sơ đồ phân loại bao quát cho các ngôn ngữ lập trình, nên trong nhiều trường
**Lập trình meta** hay còn gọi là **siêu lập trình** là việc tiến hành một trong hai thao tác (hay cả hai) sau: * Công việc viết một chương trình máy tính mà chương trình
**Python** () là ngôn ngữ lập trình bậc cao đa năng. Triết lý thiết kế của nó nhấn mạnh khả năng đọc mã bằng cách sử dụng thụt lề đáng kể. Python có kiểu động
nhỏ|Ảnh chụp màn hình tài liệu [[API web viết bởi NASA]] Một **giao diện lập trình ứng dụng** (, viết tắt: _API_) là một giao diện mà một hệ thống máy tính hay ứng dụng
**Máy tính bảng** (Tiếng Anh: Tablet computer hay tablet PC), là một thiết bị di động, thông thường có hệ điều hành di động và mạch xử lý, màn hình cảm ứng và viên pin
nhỏ **Trò chơi lập trình** (tiếng Anh: _Programming game_) là một trò chơi máy tính mà người chơi không có ảnh hưởng trực tiếp vào tiến trình của game. Thay vào đó, một chương trình
phải|khung|Một minh hoạ cách điệu của máy tính để bàn, bao gồm một vỏ hộp (có chứa bo mạch chủ và bộ vi xử lý), màn hình, bàn phím và chuột **Máy tính để bàn**,
**Ruby** là một ngôn ngữ lập trình hướng đối tượng, có khả năng phản ứng. Theo tác giả, Ruby chịu ảnh hưởng bởi Perl, Smalltalk, Eiffel, Ada và Lisp. Ruby cung cấp nhiều mẫu hình
Đây là các **trận đấu cờ vua giữa con người và máy tính** quan trọng. Máy tính lần đầu tiên có thể đánh bại những người chơi cờ mạnh vào cuối những năm 1980. nổi
**Kotlin** là một ngôn ngữ lập trình kiểu tĩnh chạy trên máy ảo Java (JVM) và có thể được biên dịch sang mã nguồn Java hay sử dụng cơ sở hạ tầng trình biên dịch
**Máy tính ma** là những máy tính kết nối với Internet đã bị xâm nhập bởi các hacker, virus máy tính, hoặc phần mềm trojan. Thông thường các máy tính bị xâm nhập chỉ là
nhỏ|4 khe cắm [[PCI Express (từ trên xuống dưới: x4, x16, x1 and x16), bên cạnh khe PCI 32 bit (dưới cùng)]] Trong kiến trúc máy tính, **bus** (là tên viết gọn của từ Latin
**Nền tảng máy tính**,** Nền tảng điện toán** hoặc **nền tảng** **kỹ thuật số** là môi trường trong đó một phần mềm được thực thi. Nó có thể là phần cứng hoặc hệ điều hành,
**Scratch** là một ngôn ngữ lập trình mang tính giáo dục miễn phí dựa trên các khối ngôn ngữ lập trình trực quan (VPL) và trang web chủ yếu để giáo dục lập trình, với
**B** là ngôn ngữ lập trình được phát triển tại Bell Labs vào khoảng năm 1969. Nó là thành quả của Ken Thompson và Dennis Ritchie. B có nguồn gốc từ BCPL, và tên gọi
**C** là một ngôn ngữ mệnh lệnh được phát triển từ đầu thập niên 1970 bởi Dennis Ritchie để dùng trong hệ điều hành UNIX. Từ đó, ngôn ngữ này đã lan rộng ra nhiều
**Java** (phiên âm Tiếng Việt: "_Gia-va_") là một ngôn ngữ lập trình hướng đối tượng, dựa trên lớp được thiết kế để có càng ít phụ thuộc thực thi càng tốt. Nó là ngôn ngữ
**C#** (**C Sharp**, đọc là _"xi-sáp"_) là một ngôn ngữ lập trình hướng đối tượng đa năng, mạnh mẽ được phát triển bởi Microsoft, C# là phần khởi đầu cho kế hoạch .NET của họ.
thumb|right|[[Hunter Biden năm 2014]] Vào tháng 10 năm 2020, một cuộc tranh cãi nổ ra liên quan đến một chiếc máy tính xách tay được cho là thuộc về Hunter Biden. Chủ một cửa hàng
nhỏ|Cbmain Trong khoa học máy tính, một **ngôn ngữ lập trình bậc cao** (tiếng Anh: _high-level programming language_) là một ngôn ngữ lập trình có sự trừu tượng hóa mạnh mẽ khỏi các chi tiết