Semântica de Cópia
Parte da seção Programação Orientada a Objetos do Journey de R da Coddy. Lição 39 de 57.
Objetos S3 e S4 são valores: uma função que altera um deles altera sua própria cópia. Objetos RC são referências: o objeto do chamador é alterado. A mesma função se comporta de maneira diferente para os dois tipos:
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)Saída:
1 2$copy() cria um novo objeto independente com os mesmos valores dos campos. Alterar a cópia não afeta o original:
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)Saída:
0 100Uma lista pode conter o mesmo objeto RC várias vezes. Alterar um elemento altera todos eles. Crie um novo objeto para cada elemento quando eles precisarem ser independentes:
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)Saída:
5 0identical(a, b) é TRUE para dois nomes do mesmo objeto RC e FALSE para uma cópia, mesmo enquanto os campos ainda são iguais:
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)Saída:
TRUE FALSE TRUEDesafio
FácilUm editor de texto mantém pontos de salvamento. Declare a classe de referência Document em Document.R com o campo text (caractere) e um método type(s) que acrescenta s ao texto. Em seguida, escreva checkpoint(doc), que retorna uma cópia independente do documento.
A definição com métodos é envolvida por suppressMessages(). O código fornecido começa com um ponto de salvamento e, em seguida, lê comandos: save armazena checkpoint(doc), undo volta para uma cópia do último ponto de salvamento e qualquer outra linha é digitada. Ele imprime o texto e o texto salvo após cada comando, portanto um ponto de salvamento nunca deve ser alterado quando a digitação continua.
Seu código deve ser colocado em Document.R. main.R contém o código fornecido de entrada/saída e não pode ser editado.
Experimente você mesmo
source("Document.R")
# Código de entrada/saída fornecido: mantenha-o como está
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 = "")
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos do S3
Trabalhando com ArquivosListas com uma ClasseFunções ConstrutorasMétodos de Impressão e FormataçãoValidadores e AuxiliaresRevisão - Temperaturas4Encapsulamento em R
Closures como ObjetosAmbientes como ObjetosFunções de AcessoProtegendo o EstadoRecapitulação - Parquímetro2Genéricos e Métodos S3
Genéricos e UseMethodMétodos padrãoMétodos para genéricos baseFundamentos de NextMethodRevisão - Áreas de formas5Classes S4
Definindo classes S4Slots e acessoVerificações de validadeMétodos showRevisão - Catálogo de produtos8Classes de Referência
Definindo Classes de ReferênciaMétodos e Atualizações de CamposSemântica de CópiaHerança e callSuperRecapitulação — Fila de Tarefas11Projeto: Gerenciamento de Biblioteca
Livros e MembrosEmpréstimo de LivrosPratique por conta própria: Compilador de R online