Closures mit Zustand
Teil des Abschnitts Logik und Ablaufsteuerung der R-Journey von Coddy. Lektion 30 von 64.
Innerhalb einer Funktion erstellt <- eine lokale Variable. Der Operator <<- weist stattdessen der Variable mit demselben Namen in der umschließenden Funktion einen Wert zu, sodass eine Closure einen von ihr erfassten Wert aktualisieren kann:
make_counter <- function() {
count <- 0
function() {
count <<- count + 1
count
}
}
next_id <- make_counter()
print(next_id())
print(next_id())
print(next_id())Ausgabe:
[1] 1
[1] 2
[1] 3Jeder von der Erzeugerfunktion erstellte Zähler hat seinen eigenen count, sodass sie sich niemals gegenseitig beeinflussen:
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())Ausgabe:
[1] 3
[1] 1Mit einem einfachen <- innerhalb der Closure erstellt die Aktualisierung eine neue lokale Variable, die nach jedem Aufruf verschwindet, und der gespeicherte Wert ändert sich nie:
make_broken <- function() {
count <- 0
function() {
count <- count + 1
count
}
}
f <- make_broken()
for (i in 1:2) f()
print(f())Ausgabe:
[1] 1Eine Factory kann eine Liste von Closures zurückgeben, die dieselben Variablen gemeinsam nutzen. Zusammen verhalten sie sich wie ein kleines Objekt mit eigenen Daten:
make_wallet <- function(balance) {
list(
add = function(x) balance <<- balance + x,
get = function() balance
)
}
w <- make_wallet(10)
w$add(5)
print(w$get())Ausgabe:
[1] 15Aufgabe
EinfachVervollständige make_counter(). Sie gibt eine Funktion zurück, die bei jedem Aufruf ihren eigenen Zähler um 1 erhöht und den neuen Zählerstand zurückgibt, beginnend bei 1.
Der bereitgestellte Code erstellt zwei Zähler, a und b. Er liest eine durch Kommas getrennte Liste aus a und b, ruft für jeden Eintrag den passenden Zähler auf und gibt jeden zurückgegebenen Wert in einer eigenen Zeile aus.
Probier es selbst
make_counter <- function() {
# Schreibe deinen Code hier
function() 0
}
# Mitgelieferter Ein-/Ausgabecode: belasse ihn unverändert
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 = "")
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Logik und Ablaufsteuerung
1Strings im Detail
Teilstrings mit substr()Formatierung mit sprintf()Aufteilen und VerbindenStrings durchsuchenText ersetzenWiederholung – Benutzernamen-Generator4Matrizen
Matrizen erstellenMatrizen indizierenZusammenfassungen von Zeilen und SpaltenMatrizenarithmetikRückblick – Sitzplan10Fortgeschrittener Kontrollfluss
Die switch()-FunktionVektorisierter ifelse()repeat und breakRekursive FunktionenRückblick – Notenklassifizierung2Schlüssel-Wert-Suchen
Benannte Vektor-SuchenSchlüssel prüfenSchlüssel hinzufügen und entfernenNamen durchlaufenRückblick – Aktienübersicht5Projekt – Notenbuch
Schüler hinzufügenNoten eintragen3Mengen und Zählen
Eindeutige WerteMengenoperationenZugehörigkeitstestsZählen mit table()Rückblick – Gäste einer Veranstaltung6Funktionen als Werte
Anonyme FunktionenFunktionen übergebenFunktionen zurückgebenClosures mit ZustandRückblick – Rabattregeln9Datenrahmen
Datenrahmen erstellenSpalten und ZeilenZeilen filternHinzufügen und SortierenZusammenfassung – Verkaufsbericht12Projekt – Ausgaben-Tracker
Ausgaben erfassenGesamtausgabenÜbe selbstständig: Online-R-Compiler