带状态的闭包
本课属于 Coddy R 学习旅程的“逻辑与流程”单元。第 30 课,共 64 课。
在函数内部,<- 会创建一个局部变量。运算符 <<- 则会赋值给外层函数中同名的变量,因此闭包可以更新它捕获的值:
make_counter <- function() {
count <- 0
function() {
count <<- count + 1
count
}
}
next_id <- make_counter()
print(next_id())
print(next_id())
print(next_id())输出:
[1] 1
[1] 2
[1] 3每个由创建器创建的计数器都有自己的 count,因此它们不会互相影响:
make_counter <- function() {
count <- 0
function() {
count <<- count + 1
count
}
}
a <- make_counter()
b <- make_counter()
for (i in 1:2) a()
print(a())
print(b())输出:
[1] 3
[1] 1在闭包中使用普通的 <- 时,每次调用都会创建一个新的局部变量,调用结束后它就会消失,存储的值也不会改变:
make_broken <- function() {
count <- 0
function() {
count <- count + 1
count
}
}
f <- make_broken()
for (i in 1:2) f()
print(f())输出:
[1] 1工厂函数可以返回共享同一组变量的闭包列表。它们组合在一起,就像一个拥有自身数据的小对象:
make_wallet <- function(balance) {
list(
add = function(x) balance <<- balance + x,
get = function() balance
)
}
w <- make_wallet(10)
w$add(5)
print(w$get())输出:
[1] 15挑战
简单补全 make_counter()。它返回一个函数,每次调用时都会将自己的计数加 1,并返回新的计数,计数从 1 开始。
提供的代码会创建两个计数器:a 和 b。代码会读取由逗号分隔的 a 和 b 列表,对每个条目调用对应的计数器,并将每个返回值单独打印在一行上。
亲手试试
make_counter <- function() {
# 在这里编写你的代码
function() 0
}
# 提供的输入和输出代码:保持原样
input <- suppressWarnings(readLines(file("stdin")))
counters <- list(a = make_counter(), b = make_counter())
for (k in strsplit(input[1], ",")[[1]]) cat(counters[[k]](), "\n", sep = "")
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
逻辑与流程中的所有课
自己练习: R 在线编译器