복사 의미론
Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 39번째.
S3 및 S4 객체는 값입니다. 하나를 변경하는 함수는 자신의 복사본을 변경합니다. RC 객체는 참조입니다. 호출자의 객체가 변경됩니다. 동일한 함수가 두 종류에 대해 다르게 동작합니다:
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)출력:
1 2$copy()는 동일한 필드 값을 가진 새롭고 독립적인 객체를 생성합니다. 복사본을 변경해도 원본에는 영향을 주지 않습니다:
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)출력:
0 100리스트는 동일한 RC 객체를 여러 번 담을 수 있습니다. 한 요소를 변경하면 모든 요소가 변경됩니다. 각 요소가 서로 독립적이어야 할 때는 요소마다 새 객체를 만드세요:
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)출력:
5 0identical(a, b)는 동일한 RC 객체를 가리키는 두 이름에 대해 TRUE이고, 필드가 여전히 같더라도 복사본에 대해서는 FALSE입니다:
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)출력:
TRUE FALSE TRUE챌린지
쉬움텍스트 편집기는 저장 지점을 유지합니다. Document.R에서 필드 text(문자형)와 텍스트에 s를 추가하는 메서드 type(s)를 포함하는 참조 클래스 Document를 선언하세요. 그런 다음 문서의 독립적인 복사본을 반환하는 checkpoint(doc)를 작성하세요.
메서드가 포함된 정의는 suppressMessages()로 감싸져 있습니다. 제공된 코드는 저장 지점에서 시작한 다음 명령을 읽습니다. save는 checkpoint(doc)를 저장하고, undo는 마지막 저장 지점의 복사본으로 돌아가며, 그 외의 줄은 입력됩니다. 각 명령 후 텍스트와 저장된 텍스트를 출력하므로, 이후에 입력을 계속해도 저장 지점은 절대 변경되지 않아야 합니다.
코드는 Document.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 들어 있으며 편집할 수 없습니다.
직접 해보기
source("Document.R")
# 제공된 입력/출력 코드: 그대로 유지하세요
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 = "")
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 R 컴파일러