Closures als Objekte
Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 17 von 57.
Du hast Closures in Logic & Flow kennengelernt: Eine innerhalb einer anderen Funktion erstellte Funktion behält die Variablen um sie herum bei. Eine Funktionsfabrik, die eine Liste solcher Funktionen zurückgibt, erstellt ein Objekt. Ihre lokalen Variablen sind die Daten des Objekts, und die Funktionen sind seine Methoden:
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())Ausgabe:
[1] 150Jeder Aufruf der Factory führt ihren Rumpf erneut aus, sodass jedes Objekt seine eigenen Variablen erhält. Das Ändern eines Kontos wirkt sich nicht auf das andere aus:
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())Ausgabe:
101 5Die Daten sind privat. balance ist kein Element der Liste, daher ist acc$balance NULL, und eine Zuweisung daran fügt lediglich ein unabhängiges Element hinzu. Die Funktionen in der Liste bilden die gesamte öffentliche Schnittstelle des Objekts:
make_account <- function(balance = 0) {
list(get_balance = function() balance)
}
acc <- make_account(100)
print(acc$balance)
acc$balance <- 1e6
print(acc$get_balance())Ausgabe:
NULL
[1] 100Die Methoden können einander aufrufen, wenn sie als lokale Funktionen definiert werden, bevor die Liste erstellt wird. Hier verwendet add_many() add() erneut:
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())Ausgabe:
[1] 10Aufgabe
EinfachVervollständige die Factory make_counter(start = 0) in Counter.R. Sie hält den aktuellen Wert privat und gibt eine Liste mit vier Funktionen zurück: increment() und decrement() ändern den Wert um 1, reset() setzt ihn auf start zurück, und value() gibt ihn zurück.
Der bereitgestellte Code liest den Startwert und anschließend die Befehle +, - oder reset ein und gibt den Wert nach jedem Befehl aus. Am Ende gibt er die Namen in der zurückgegebenen Liste aus; diese darf nur die vier Funktionen enthalten.
Dein Code gehört in Counter.R. main.R enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
source("Counter.R")
# Bereitgestellter Ein-/Ausgabe-Code: belasse ihn wie er ist
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 = "")
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1S3-Grundlagen
Arbeiten mit DateienListen mit einer KlasseKonstruktorfunktionenPrint- und Format-MethodenValidatoren und HilfsfunktionenRückblick – Temperaturen4Kapselung in R
Closures als ObjekteUmgebungen als ObjekteZugriffsfunktionenZustand schützenRückblick – Parkuhr2S3-Generics und Methoden
Generics und UseMethodStandardmethodenMethoden für Basis-GenericsGrundlagen von NextMethodWiederholung – Flächeninhalte von Formen5S4-Klassen
S4-Klassen definierenSlots und ZugriffGültigkeitsprüfungenShow-MethodenRückblick – Produktkatalog8Referenzklassen
Referenzklassen definierenMethoden und FeldänderungenKopiersemantikVererbung und callSuperZusammenfassung – Aufgabenwarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Online-R-Compiler