状態を持つクロージャ
CoddyのRジャーニー「ロジックとフロー」セクションの一部。レッスン 30/64。
関数内では、<- がローカル変数を作成します。演算子 <<- は代わりに、外側の関数にある同じ名前の変数に代入するため、クロージャはキャプチャした値を更新できます。
make_counter <- function() {
count <- 0
function() {
count <<- count + 1
count
}
}
next_id <- make_counter()
print(next_id())
print(next_id())
print(next_id())出力:
[1] 1
[1] 2
[1] 3maker によって作られた各カウンターはそれぞれ独自の count を持つため、互いに干渉することはありません。
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())出力:
[1] 3
[1] 1クロージャ内で通常の <- を使うと、更新によって呼び出しごとに消える新しいローカル変数が作成され、保存された値は決して変化しません。
make_broken <- function() {
count <- 0
function() {
count <- count + 1
count
}
}
f <- make_broken()
for (i in 1:2) f()
print(f())出力:
[1] 1メーカーは、同じ変数を共有するクロージャのリストを返すことができます。これらは一緒になると、独自のデータを持つ小さなオブジェクトのように動作します:
make_wallet <- function(balance) {
list(
add = function(x) balance <<- balance + x,
get = function() balance
)
}
w <- make_wallet(10)
w$add(5)
print(w$get())出力:
[1] 15チャレンジ
簡単make_counter()を完成させてください。これは、呼び出されるたびに自身のカウントに1を加え、新しいカウントを返す関数を返します。カウントは1から始まります。
提供されたコードは、aとbという2つのカウンターを作成します。aとbのカンマ区切りリストを読み込み、各項目に対応するカウンターを呼び出し、返された各値をそれぞれ独自の行に出力します。
自分で試してみよう
make_counter <- function() {
# ここにコードを書いてください
function() 0
}
# 提供された入出力コード:そのままにしておいてください
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 = "")
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
ロジックとフローのすべてのレッスン
自分で練習してみよう: Rオンラインコンパイラ