Go – Defer

Defer

Câu lệnh defer là cách tiện lợi để chạy một đoạn code trước khi hàm trả về. Defer luôn được kích hoạt ở cuối hàm, thậm trí kể cả những đoạn code không được kiểm soát lỗi và là nguyên nhân gây chương trình bị tạm dừng, thì nó vẫn đảm bảo rằng Defer code được chạy. Định nghĩa này nghe có vẻ phức tạp nhưng thực tế nó tương đối dễ hiểu thông qua ví dụ

Kết quả

Ví dụ bên trên là tìm số lớn nhất của slice truyền vào. Hàm largest nhận int slice như một tham số truyền vào rồi in ra số lớn nhất. Hàng đầu tiên của hàm có câu lệnh defer finished(), nghĩa là hàm finished() sẽ chỉ được gọi khi hàm largest trả về.

Phương thức

Defer không chỉ giới hạn sử dụng trong hàm, nó hoàn toàn có thể sử dụng cho gọi phương thức. Hãy thử xem ví dụ sau

Kết quả

Trong hàm main(), chúng ta gọi defer p.fullname(), nên fullname của của person được in ra sau cùng, khi chương trình chạy xong.

Tính toán tham số

Tham số của hàm Defer được tính toán khi câu lệnh defer được chạy và không phải là khi gọi hàm mới thực hiện tính toán. Hãy cùng xem ví dụ sau

Biến a được khởi tạo với giá trị bằng 5. Khi câu lệnh defer được chạy, giá trị của a5 và vì thế đây sẽ là tham số được truyền vào hàm printA. Chúng ta cũng đã thay đổi giá trị của a nằm dưới defer, hàng tiếp theo phía sau printA.

Kết quả

Stack defer

Khi một hàm gọi nhiều defer, chúng sẽ được thêm vào stack và được gọi theo thứ tự Last In First Out (LIFO)

Chúng ta sẽ viết một ví dụ dùng để in ra một chuỗi đảo ngược sử dụng stack

Trong đoạn code bên trên, vòng lặp for range thực hiện lặp một chuỗi và gọi defer fmt.Printf("%c", v). Các defer này sẽ được thêm vào stack và gọi theo thứ tự LIFO và do đó chuỗi được in ra theo thứ tự đảo ngược

Kết quả

Panic

Hãy cùng xem ví dụ sau về code Panic

Code bên trên sử dụng đệ quy và chúng ta sẽ có một panic khi count lớn hơn 3. fmt.Sprintf dùng để định dạng một string dựa trên giá trị. Điều này là bắt buộc vì tham số của hàm panic yêu cầu một string.

Ngoài ra hàm recover() có phép chúng ta lấy lại từ panic xuống stack được gọi. recover này gọi đến hàm defer anonymous, chúng ta cần đảm bảo rằng nó sẽ luôn luôn được gọi khi gọi deferPanicExample.

Kết quả

 

You May Also Like

About the Author: Nguyen Dinh Thuc

Leave a Reply

avatar
  Subscribe  
Notify of