<<-
状態を維持するためにクロージャーと組み合わせて最も役立ちます。これが私の最近の論文のセクションです:
クロージャは、別の関数によって記述された関数です。クロージャは、親関数の環境を囲み、その関数のすべての変数とパラメーターにアクセスできるため、いわゆるクロージャです。これは、2つのレベルのパラメーターを持つことができるので便利です。1つのレベルのパラメーター(親)は、関数の動作を制御します。他のレベル(子)が作業を行います。次の例は、このアイデアを使用して一連の電力関数を生成する方法を示しています。親関数( )は、実際にハードワークを実行power
する子関数(square
および)を作成します。cube
power <- function(exponent) {
function(x) x ^ exponent
}
square <- power(2)
square(2) # -> [1] 4
square(4) # -> [1] 16
cube <- power(3)
cube(2) # -> [1] 8
cube(4) # -> [1] 64
2つのレベルで変数を管理する機能により、関数がその親の環境で変数を変更できるようにすることで、関数の呼び出し全体で状態を維持することもできます。さまざまなレベルで変数を管理するための鍵は、二重矢印代入演算子 <<-
です。現在のレベルで常に機能する通常の単一矢印の割り当て(<-
)とは異なり、二重矢印演算子は親レベルの変数を変更できます。
これにより、次の例に示すように、関数が呼び出された回数を記録するカウンターを維持できます。実行するたびnew_counter
に、環境を作成し、この環境でカウンターi
を初期化してから、新しい関数を作成します。
new_counter <- function() {
i <- 0
function() {
# do something useful, then ...
i <<- i + 1
i
}
}
新しい関数はクロージャであり、その環境は囲み環境です。クロージャcounter_one
とcounter_two
が実行されると、それぞれがそれを囲む環境のカウンタを変更してから、現在のカウントを返します。
counter_one <- new_counter()
counter_two <- new_counter()
counter_one() # -> [1] 1
counter_one() # -> [1] 2
counter_two() # -> [1] 1