Menu
CoddyTech

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'da closure'ları gördünüz: bir işlevin içinde oluşturulan bir işlev, çevresindeki değişkenleri korur. 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, işlevler ise 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

Veri ö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 dosyasında tamamla. Mevcut değeri özel tutar ve dört işlevden oluşan bir liste döndürür: increment() ve decrement() değeri 1 artırır ve azaltır, reset() değeri yeniden start yapar ve value() değeri döndürür.

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

Kodunu Counter.R dosyasına yaz. main.R, verilen 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