Kopiersemantik
Teil des Abschnitts Objektorientierte Programmierung der R-Journey von Coddy. Lektion 39 von 57.
S3- und S4-Objekte sind Werte: Eine Funktion, die eines ändert, ändert ihre eigene Kopie. RC-Objekte sind Referenzen: Das Objekt des Aufrufers ändert sich. Dieselbe Funktion verhält sich bei den beiden Arten unterschiedlich:
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)Ausgabe:
1 2$copy() erstellt ein neues, unabhängiges Objekt mit denselben Feldwerten. Wenn du die Kopie änderst, bleibt das Original unverändert:
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)Ausgabe:
0 100Eine Liste kann dasselbe RC-Objekt mehrmals enthalten. Wenn ein Element geändert wird, ändern sich dadurch alle. Erstelle für jedes Element ein neues Objekt, wenn sie unabhängig voneinander sein müssen:
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)Ausgabe:
5 0identical(a, b) ist TRUE für zwei Namen desselben RC-Objekts und FALSE für eine Kopie, selbst wenn die Felder weiterhin gleich sind:
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)Ausgabe:
TRUE FALSE TRUEAufgabe
EinfachEin Texteditor speichert Sicherungspunkte. Deklariere die Referenzklasse Document in Document.R mit dem Feld text (character) und einer Methode type(s), die s an den Text anhängt. Schreibe anschließend checkpoint(doc), das eine unabhängige Kopie des Dokuments zurückgibt.
Die Definition mit Methoden ist in suppressMessages() eingeschlossen. Der bereitgestellte Code beginnt mit einem Sicherungspunkt und liest anschließend Befehle: save speichert checkpoint(doc), undo kehrt zu einer Kopie des letzten Sicherungspunkts zurück, und jede andere Zeile wird eingegeben. Nach jedem Befehl gibt er den Text und den gespeicherten Text aus, daher darf sich ein Sicherungspunkt beim weiteren Eingeben niemals ändern.
Dein Code gehört in Document.R. main.R enthält den bereitgestellten Eingabe-/Ausgabecode und darf nicht bearbeitet werden.
Probier es selbst
source("Document.R")
# Gelieferter Input/Output-Code: belasse ihn wie er ist
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 = "")
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1S3-Grundlagen
Arbeiten mit DateienListen mit einer KlasseKonstruktorfunktionenPrint- und Format-MethodenValidatoren und HilfsfunktionenRückblick – Temperaturen4Kapselung in R
Closures als ObjekteUmgebungen als ObjekteZugriffsfunktionenZustand schützenRückblick – Parkuhr2S3-Generics und Methoden
Generics und UseMethodStandardmethodenMethoden für Basis-GenericsGrundlagen von NextMethodWiederholung – Flächeninhalte von Formen5S4-Klassen
S4-Klassen definierenSlots und ZugriffGültigkeitsprüfungenShow-MethodenRückblick – Produktkatalog8Referenzklassen
Referenzklassen definierenMethoden und FeldänderungenKopiersemantikVererbung und callSuperZusammenfassung – Aufgabenwarteschlange11Projekt: Bibliotheksverwaltung
Bücher und MitgliederBücher ausleihenÜbe selbstständig: Online-R-Compiler