Menu
Coddy logo textTech

Nesne Olarak Closure'lar

Coddy'nin R Journey'sinin Nesne Tabanlı Programlama bölümünün bir parçası. Ders 17 / 57.

Logic & Flow bölümünde kapanışlarla tanıştınız: bir işlevin başka bir işlevin içinde oluşturulması, çevresindeki değişkenleri korumasını sağlar. Bu tür işlevlerden oluşan bir liste döndüren bir işlev fabrikası bir nesne oluşturur. Yerel değişkenleri nesnenin verileridir ve işlevler de yöntemleridir:

make_account <- function(balance = 0) {
  deposit <- function(x) balance <<- balance + x
  get_balance <- function() balance
  list(deposit = deposit, get_balance = get_balance)
}
acc <- make_account(100)
acc$deposit(50)
print(acc$get_balance())

Çıktı:

[1] 150

Fabrikanın her çağrısı gövdesini yeniden çalıştırır; bu nedenle her nesne kendi değişkenlerine sahip olur. Bir hesabı değiştirmek diğerini etkilemez:

make_account <- function(balance = 0) {
  list(deposit = function(x) balance <<- balance + x,
       get_balance = function() balance)
}
ada <- make_account(100)
bo <- make_account(5)
ada$deposit(1)
cat(ada$get_balance(), bo$get_balance())

Çıktı:

101 5

Veriler özeldir. balance listenin bir öğesi değildir; bu nedenle acc$balance değeri NULL olur ve buna atama yapmak yalnızca ilgisiz bir öğe ekler. Listedeki işlevler, nesnenin tüm genel arayüzünü oluşturur:

make_account <- function(balance = 0) {
  list(get_balance = function() balance)
}
acc <- make_account(100)
print(acc$balance)
acc$balance <- 1e6
print(acc$get_balance())

Çıktı:

NULL
[1] 100

Yöntemler, liste oluşturulmadan önce yerel işlevler olarak tanımlandıklarında birbirlerini çağırabilir. Burada add_many(), add() işlevini yeniden kullanır:

make_tally <- function() {
  total <- 0
  add <- function(x) total <<- total + x
  add_many <- function(xs) for (x in xs) add(x)
  get <- function() total
  list(add = add, add_many = add_many, get = get)
}
t <- make_tally()
t$add(1)
t$add_many(c(2, 3, 4))
print(t$get())

Çıktı:

[1] 10
challenge icon

Görev

Kolay

make_counter(start = 0) fabrikasını Counter.R içinde tamamla. Geçerli değeri gizli tutar ve dört işlev içeren bir liste döndürür: increment() ve decrement() değeri 1 artırır veya azaltır, reset() değeri tekrar start olarak ayarlar ve value() değeri döndürür.

Sağlanan kod başlangıç değerini, ardından +, - veya reset komutlarını okur ve her birinden sonra değeri yazdırır. Sonunda döndürülen listedeki adları yazdırır; bu liste yalnızca dört işlev içermelidir.

Kodun Counter.R içine yazılmalıdır. main.R, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

source("Counter.R")

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
counter <- make_counter(as.numeric(input[1]))
for (cmd in input[-1]) {
  if (cmd == "+") counter$increment()
  if (cmd == "-") counter$decrement()
  if (cmd == "reset") counter$reset()
  cat(cmd, " -> ", counter$value(), "\n", sep = "")
}
cat("fields visible: ", paste(sort(names(counter)), collapse = ", "), "\n", sep = "")
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Nesne Tabanlı Programlama bölümündeki tüm dersler

Kendi başına pratik yap: Online R derleyicisi