Domknięcia ze stanem
Część sekcji Logika i przepływ sterowania ścieżki R w Coddy. Lekcja 30 z 64.
Wewnątrz funkcji operator <- tworzy zmienną lokalną. Operator <<- przypisuje wartość do zmiennej o tej samej nazwie w funkcji zewnętrznej, dzięki czemu domknięcie może aktualizować przechwyconą wartość:
make_counter <- function() {
count <- 0
function() {
count <<- count + 1
count
}
}
next_id <- make_counter()
print(next_id())
print(next_id())
print(next_id())Wynik:
[1] 1
[1] 2
[1] 3Każdy licznik utworzony przez funkcję tworzącą ma własne count, więc liczniki nigdy na siebie nie wpływają:
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())Wynik:
[1] 3
[1] 1Przy zwykłym <- wewnątrz domknięcia aktualizacja tworzy nową zmienną lokalną, która znika po każdym wywołaniu, a przechowywana wartość nigdy się nie zmienia:
make_broken <- function() {
count <- 0
function() {
count <- count + 1
count
}
}
f <- make_broken()
for (i in 1:2) f()
print(f())Wynik:
[1] 1Funkcja tworząca może zwrócić listę domknięć, które współdzielą te same zmienne. Razem zachowują się jak mały obiekt z własnymi danymi:
make_wallet <- function(balance) {
list(
add = function(x) balance <<- balance + x,
get = function() balance
)
}
w <- make_wallet(10)
w$add(5)
print(w$get())Wynik:
[1] 15Wyzwanie
ŁatwyUzupełnij make_counter(). Zwraca funkcję, która za każdym razem, gdy zostanie wywołana, zwiększa swój licznik o 1 i zwraca nową wartość, zaczynając od 1.
Dostarczony kod tworzy dwa liczniki: a i b. Odczytuje rozdzieloną przecinkami listę a i b, wywołuje pasujący licznik dla każdego elementu i wypisuje każdą zwróconą wartość w osobnym wierszu.
Spróbuj swoich sił
make_counter <- function() {
# Wpisz tutaj swój kod
function() 0
}
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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 = "")
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Logika i przepływ sterowania
1Łańcuchy znaków w szczegółach
Podciągi za pomocą substr()Formatowanie za pomocą sprintf()Dzielenie i łączenieWyszukiwanie w łańcuchach znakówZastępowanie tekstuPowtórka – kreator nazwy użytkownika4Macierze
Tworzenie macierzyIndeksowanie macierzyPodsumowania wierszy i kolumnDziałania na macierzachPowtórka – plan miejsc10Zaawansowane sterowanie przepływem
Funkcja switch()Wektorowe ifelse()repeat i breakFunkcje rekurencyjnePodsumowanie — klasyfikator ocen2Wyszukiwanie wartości po kluczach
Wyszukiwanie nazwanych elementów wektoraSprawdzanie kluczyDodawanie i usuwanie kluczyIterowanie po nazwachPowtórzenie — giełda5Projekt — dziennik ocen
Dodawanie uczniówZapisywanie ocen3Zbiory i zliczanie
Unikalne wartościOperacje na zbiorachTesty przynależnościZliczanie za pomocą table()Podsumowanie — goście wydarzenia6Funkcje jako wartości
Funkcje anonimowePrzekazywanie funkcjiZwracanie funkcjiDomknięcia ze stanemPowtórka — reguły rabatowe9Ramki danych
Tworzenie ramek danychKolumny i wierszeFiltrowanie wierszyDodawanie i sortowaniePodsumowanie – raport sprzedaży12Projekt – śledzenie wydatków
Rejestrowanie wydatkówŁączne wydatkiPoćwicz samodzielnie: Kompilator R online