Menu
Coddy logo textTech

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] 3

Jeder 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] 1

Mit 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] 1

Eine 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] 15
challenge icon

Aufgabe

Einfach

Vervollstä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 = "")
quiz iconTeste dich selbst

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

Übe selbstständig: Online-R-Compiler