Menu
Coddy logo textTech

Kopyalama Semantiği

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

S3 ve S4 nesneleri değerlerdir: birini değiştiren bir işlev, kendi kopyasını değiştirir. RC nesneleri referanslardır: çağıranın nesnesi değişir. Aynı işlev, bu iki tür için farklı davranır:

setClass("S4Box", slots = c(n = "numeric"))
RCBox <- setRefClass("RCBox", fields = list(n = "numeric"))
bump_s4 <- function(b) { b@n <- b@n + 1; invisible(b) }
bump_rc <- function(b) b$n <- b$n + 1
v <- new("S4Box", n = 1)
r <- RCBox$new(n = 1)
bump_s4(v)
bump_rc(r)
cat(v@n, r$n)

Çıktı:

1 2

$copy(), aynı alan değerlerine sahip yeni ve bağımsız bir nesne oluşturur. Kopyayı değiştirmek orijinali etkilemez:

Account <- setRefClass("Account", fields = list(balance = "numeric"))
a <- Account$new(balance = 100)
alias <- a
backup <- a$copy()
alias$balance <- 0
cat(a$balance, backup$balance)

Çıktı:

0 100

Bir liste aynı RC nesnesini birkaç kez tutabilir. Bir öğeyi değiştirmek, ardından hepsini değiştirir. Bağımsız olmaları gerektiğinde her öğe için yeni bir nesne oluşturun:

Counter <- setRefClass("Counter", fields = list(n = "numeric"))
one <- Counter$new(n = 0)
same <- list(one, one, one)
same[[1]]$n <- 5
fresh <- lapply(1:3, function(i) Counter$new(n = 0))
fresh[[1]]$n <- 5
cat(same[[3]]$n, fresh[[3]]$n)

Çıktı:

5 0

identical(a, b), aynı RC nesnesinin iki adı için TRUE değerini, alanlar hâlâ eşit olsa bile bir kopya için FALSE değerini döndürür:

Account <- setRefClass("Account", fields = list(balance = "numeric"))
a <- Account$new(balance = 100)
b <- a
c2 <- a$copy()
cat(identical(a, b), identical(a, c2), c2$balance == a$balance)

Çıktı:

TRUE FALSE TRUE
challenge icon

Görev

Kolay

Bir metin düzenleyicisi kayıt noktalarını tutar. Document Referans Sınıfını Document.R içinde, text alanı (character) ve metne s ekleyen type(s) yöntemiyle tanımlayın. Ardından belgenin bağımsız bir kopyasını döndüren checkpoint(doc) işlevini yazın.

Yöntemleri içeren tanım suppressMessages() içine alınır. Sağlanan kod bir kayıt noktasıyla başlar, ardından komutları okur: save, checkpoint(doc) değerini kaydeder; undo, son kayıt noktasının bir kopyasına geri döner; diğer tüm satırlar yazılır. Her komuttan sonra metni ve kaydedilen metni yazdırır; bu nedenle yazmaya devam edildiğinde bir kayıt noktası asla değişmemelidir.

Kodunuz Document.R içine gider. main.R, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.

Kendin dene

source("Document.R")

# Sağlanan girdi/çıktı kodu: olduğu gibi bırakın
input <- suppressWarnings(readLines(file("stdin")))
doc <- Document$new(text = "")
saved <- checkpoint(doc)
for (cmd in input) {
  if (cmd == "save") {
    saved <- checkpoint(doc)
  } else if (cmd == "undo") {
    doc <- checkpoint(saved)
  } else {
    doc$type(cmd)
  }
  cat(cmd, " -> [", doc$text, "] saved [", saved$text, "]\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