Closure con stato
Fa parte della sezione Logica e flusso del percorso R di Coddy. Lezione 30 di 64.
All'interno di una funzione, <- crea una variabile locale. L'operatore <<- assegna invece alla variabile con lo stesso nome nella funzione che la racchiude, così una chiusura può aggiornare un valore che ha catturato:
make_counter <- function() {
count <- 0
function() {
count <<- count + 1
count
}
}
next_id <- make_counter()
print(next_id())
print(next_id())
print(next_id())Output:
[1] 1
[1] 2
[1] 3Ogni contatore creato dal generatore ha il proprio count, quindi non interferiscono mai:
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())Output:
[1] 3
[1] 1Con un semplice <- all'interno della chiusura, l'aggiornamento crea una nuova variabile locale che scompare dopo ogni chiamata, e il valore memorizzato non cambia mai:
make_broken <- function() {
count <- 0
function() {
count <- count + 1
count
}
}
f <- make_broken()
for (i in 1:2) f()
print(f())Output:
[1] 1Una funzione creatrice può restituire un elenco di chiusure che condividono le stesse variabili. Insieme si comportano come un piccolo oggetto con i propri dati:
make_wallet <- function(balance) {
list(
add = function(x) balance <<- balance + x,
get = function() balance
)
}
w <- make_wallet(10)
w$add(5)
print(w$get())Output:
[1] 15Sfida
FacileCompleta make_counter(). Restituisce una funzione che, ogni volta che viene chiamata, aggiunge 1 al proprio conteggio e restituisce il nuovo conteggio, partendo da 1.
Il codice fornito crea due contatori, a e b. Legge un elenco di a e b separati da virgole, chiama il contatore corrispondente per ogni elemento e stampa ogni valore restituito su una propria riga.
Provalo tu
make_counter <- function() {
# Escribe tu código aquí
function() 0
}
# Código de entrada/salida proporcionado: 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 = "")
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Logica e flusso
1Le stringhe in dettaglio
Sottostringhe con substr()Formattazione con sprintf()Dividere e unireRicerca nelle stringheSostituzione del testoRipasso - Generatore di nomi utente4Matrici
Creazione di matriciIndicizzazione delle matriciRiepiloghi di righe e colonneOperazioni aritmetiche con le matriciRipasso - Schema dei posti a sedere10Flusso di controllo avanzato
La funzione switch()ifelse() vettorialerepeat e breakFunzioni ricorsiveRiepilogo - Classificatore di voti2Ricerche chiave-valore
Ricerche in vettori con nomiControllare le chiaviAggiungere e rimuovere chiaviIterare sui nomiRiepilogo - Sportello titoli5Progetto - Registro dei voti
Aggiungere studentiRegistrare i voti8Ordinamento e raggruppamento
Ordinare i vettoriOrdinare in base a una chiaveRaggruppare con split()Riepiloghi dei gruppiRipasso - Classifica3Insiemi e conteggio
Valori univociOperazioni sugli insiemiTest di appartenenzaConteggio con table()Riepilogo - Ospiti dell’evento6Le funzioni come valori
Funzioni anonimePassare funzioniRestituire funzioniClosure con statoRiepilogo - Regole di sconto9DataFrame
Creare DataFrameColonne e righeFiltrare le righeAggiungere e ordinareRiepilogo - Report delle vendite12Progetto - Gestione delle spese
Registrare le speseSpesa totaleEsercitati da solo: Compilatore R online