Chiusure come oggetti
Fa parte della sezione Programmazione orientata agli oggetti del percorso R di Coddy. Lezione 17 di 57.
Hai incontrato le closure in Logic & Flow: una funzione creata all'interno di un'altra funzione mantiene le variabili che la circondano. Una fabbrica di funzioni che restituisce un elenco di tali funzioni crea un oggetto. Le sue variabili locali sono i dati dell'oggetto e le funzioni sono i suoi metodi:
make_account <- function(balance = 0) {
deposit <- function(x) balance <<- balance + x
get_balance <- function() balance
list(deposit = deposit, get_balance = get_balance)
}
acc <- make_account(100)
acc$deposit(50)
print(acc$get_balance())Output:
[1] 150Ogni chiamata alla funzione factory esegue di nuovo il proprio corpo, quindi ogni oggetto ha le proprie variabili. Modificare un conto non influisce sull’altro:
make_account <- function(balance = 0) {
list(deposit = function(x) balance <<- balance + x,
get_balance = function() balance)
}
ada <- make_account(100)
bo <- make_account(5)
ada$deposit(1)
cat(ada$get_balance(), bo$get_balance())Output:
101 5I dati sono privati. balance non è un elemento della lista, quindi acc$balance è NULL e assegnargli un valore aggiunge solo un elemento non correlato. Le funzioni nella lista costituiscono l'intera interfaccia pubblica dell'oggetto:
make_account <- function(balance = 0) {
list(get_balance = function() balance)
}
acc <- make_account(100)
print(acc$balance)
acc$balance <- 1e6
print(acc$get_balance())Output:
NULL
[1] 100I metodi possono richiamarsi a vicenda quando sono definiti come funzioni locali prima che venga creata la lista. Qui add_many() riutilizza add():
make_tally <- function() {
total <- 0
add <- function(x) total <<- total + x
add_many <- function(xs) for (x in xs) add(x)
get <- function() total
list(add = add, add_many = add_many, get = get)
}
t <- make_tally()
t$add(1)
t$add_many(c(2, 3, 4))
print(t$get())Output:
[1] 10Sfida
FacileCompleta la factory make_counter(start = 0) in Counter.R. Mantiene privato il valore corrente e restituisce una lista con quattro funzioni: increment() e decrement() modificano il valore di 1, reset() lo reimposta a start e value() lo restituisce.
Il codice fornito legge il valore iniziale, poi i comandi +, - o reset e stampa il valore dopo ciascuno. Alla fine stampa i nomi nella lista restituita, che deve contenere solo le quattro funzioni.
Il tuo codice va in Counter.R. main.R contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
source("Counter.R")
# Supplied input/output code: keep it as it is
input <- suppressWarnings(readLines(file("stdin")))
counter <- make_counter(as.numeric(input[1]))
for (cmd in input[-1]) {
if (cmd == "+") counter$increment()
if (cmd == "-") counter$decrement()
if (cmd == "reset") counter$reset()
cat(cmd, " -> ", counter$value(), "\n", sep = "")
}
cat("fields visible: ", paste(sort(names(counter)), collapse = ", "), "\n", sep = "")
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Nozioni di base su S3
Lavorare con i fileListe con una classeFunzioni costruttriciMetodi di stampa e formattazioneValidatori e funzioni di supportoRipasso - Temperature4Incapsulamento in R
Chiusure come oggettiAmbienti come oggettiFunzioni di accessoProteggere lo statoRiepilogo - Parcometro2Generics e metodi S3
Generics e UseMethodMetodi predefinitiMetodi per i generics di baseNozioni di base su NextMethodRiepilogo - Aree delle forme5Classi S4
Definire le classi S4Slot e accessoControlli di validitàMetodi showRiepilogo - Catalogo prodotti8Classi di riferimento
Definizione delle classi di riferimentoMetodi e aggiornamenti dei campiSemantica della copiaEreditarietà e callSuperRiepilogo - coda di attività11Progetto: Gestione della biblioteca
Libri e iscrittiPrestito dei libriEsercitati da solo: Compilatore R online