<<-
hữu ích nhất cùng với các bao đóng để duy trì trạng thái. Dưới đây là một phần từ một bài báo gần đây của tôi:
Đóng là một hàm được viết bởi một hàm khác.Các bao đóng được gọi như vậy bởi vì chúng đính kèm môi trường của hàm cha và có thể truy cập tất cả các biến và tham số trong hàm đó. Điều này rất hữu ích vì nó cho phép chúng ta có hai mức tham số. Một mức tham số (cha mẹ) kiểm soát cách hoạt động của hàm. Cấp độ khác (đứa trẻ) thực hiện công việc. Ví dụ sau đây cho thấy làm thế nào có thể sử dụng ý tưởng này để tạo ra một gia đình của các chức năng quyền lực. Hàm cha (power
) tạo các hàm con (square
và cube
) thực sự làm công việc khó khăn.
power <- function(exponent) {
function(x) x^exponent
}
square <- power(2)
square(2) # -> [1] 4
square(4) # -> [1] 16
cube <- power(3)
cube(2) # -> [1] 8
cube(4) # -> [1] 64
Khả năng quản lý biến ở hai cấp độ cũng có thể duy trì trạng thái qua các lần gọi hàm bằng cách cho phép sửa đổi các biến trong môi trường của cha mẹ. Chìa khóa để quản lý các biến ở các cấp khác nhau là toán tử gán mũi tên kép <<-
. Không giống như việc gán mũi tên đơn thông thường (<-
) luôn hoạt động ở cấp hiện tại, toán tử mũi tên đôi có thể sửa đổi các biến ở cấp độ gốc.
Điều này giúp duy trì bộ đếm ghi lại số lần hàm được gọi, như ví dụ sau đây. Mỗi lần new_counter
được chạy, nó tạo ra một môi trường, khởi tạo bộ đếm i
trong môi trường này và sau đó tạo một hàm mới.
new_counter <- function() {
i <- 0
function() {
# do something useful, then ...
i <<- i + 1
i
}
}
Chức năng mới là đóng cửa và môi trường của nó là môi trường kèm theo. Khi đóng cửa counter_one
và counter_two
được chạy, mỗi lần sửa đổi bộ đếm trong môi trường kèm theo của nó và sau đó trả về số đếm hiện tại.
counter_one <- new_counter()
counter_two <- new_counter()
counter_one() # -> [1] 1
counter_one() # -> [1] 2
counter_two() # -> [1] 1
Đây là một nhiệm vụ R chưa được giải quyết trên Rosettacode (http://rosettacode.org/wiki/Accumulator_factory#R) Vâng, nó là ... –
Sẽ có bất kỳ nhu cầu nào kèm theo nhiều hơn 1 đóng trong một hàm cha? Tôi vừa thử một đoạn, có vẻ như chỉ việc đóng cửa cuối cùng được thực hiện ... –