Clausuras con estado
Parte de la sección Lógica y flujo del Journey de R de Coddy. Lección 30 de 64.
Dentro de una función, <- crea una variable local. En su lugar, el operador <<- asigna a la variable con el mismo nombre en la función envolvente, por lo que un cierre puede actualizar un valor que capturó:
make_counter <- function() {
count <- 0
function() {
count <<- count + 1
count
}
}
next_id <- make_counter()
print(next_id())
print(next_id())
print(next_id())Salida:
[1] 1
[1] 2
[1] 3Cada contador creado por el creador tiene su propio count, por lo que nunca interfieren:
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())Salida:
[1] 3
[1] 1Con un <- simple dentro del cierre, la actualización crea una nueva variable local que desaparece después de cada llamada, y el valor almacenado nunca cambia:
make_broken <- function() {
count <- 0
function() {
count <- count + 1
count
}
}
f <- make_broken()
for (i in 1:2) f()
print(f())Salida:
[1] 1Una fábrica puede devolver una lista de cierres que comparten las mismas variables. Juntos se comportan como un pequeño objeto con sus propios datos:
make_wallet <- function(balance) {
list(
add = function(x) balance <<- balance + x,
get = function() balance
)
}
w <- make_wallet(10)
w$add(5)
print(w$get())Salida:
[1] 15Desafío
FácilCompleta make_counter(). Devuelve una función que, cada vez que se llama, suma 1 a su propio contador y devuelve el nuevo contador, empezando desde 1.
El código proporcionado crea dos contadores, a y b. Lee una lista separada por comas de a y b, llama al contador correspondiente para cada entrada e imprime cada valor devuelto en su propia línea.
Pruébalo tú mismo
make_counter <- function() {
# Escribe tu código aquí
function() 0
}
# Código de entrada/salida suministrado: mantenlo tal como está
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 = "")
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Lógica y flujo
1Cadenas a fondo
Subcadenas con substr()Formateo con sprintf()Dividir y unirBuscar cadenasReemplazar textoRepaso - Constructor de nombres de usuario4Matrices
Creación de matricesIndexación de matricesResúmenes de filas y columnasAritmética de matricesRepaso: tabla de asientos2Búsquedas clave-valor
Búsquedas en vectores con nombreComprobar clavesAñadir y eliminar clavesRecorrer nombresRepaso: panel bursátil5Proyecto - Libro de calificaciones
Añadir estudiantesRegistrar calificaciones3Conjuntos y conteo
Valores únicosOperaciones con conjuntosPruebas de pertenenciaConteo con table()Repaso: invitados al evento6Funciones como valores
Funciones anónimasPasar funcionesDevolver funcionesClausuras con estadoRepaso: reglas de descuento9Marcos de datos
Creación de marcos de datosColumnas y filasFiltrado de filasAdición y ordenaciónRepaso - Informe de ventas12Proyecto: Rastreador de gastos
Registro de gastosGasto totalPractica por tu cuenta: Compilador de R online