객체로서의 환경
Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 18번째.
환경은 new.env()로 생성되는 목록과 같은 이름이 지정된 값의 집합입니다. 차이점은 환경은 절대 복사되지 않는다는 것입니다. 환경을 참조하는 모든 변수는 동일한 객체를 보므로, 한 이름을 통해 변경한 내용이 다른 모든 이름을 통해서도 보입니다:
e <- new.env()
e$count <- 1
alias <- e
alias$count <- 99
print(e$count)
l <- list(count = 1)
copy <- l
copy$count <- 99
print(l$count)출력:
[1] 99
[1] 1환경을 전달받는 함수는 호출자의 객체를 변경합니다. 아무것도 반환할 필요가 없으며, 호출자는 결과를 할당하지 않습니다:
deposit <- function(acc, x) acc$balance <- acc$balance + x
acc <- new.env()
acc$balance <- 10
deposit(acc, 5)
deposit(acc, 5)
print(acc$balance)출력:
[1] 20assign(), get() 및 exists()는 변수에 저장된 이름을 사용하며, ls()는 환경의 이름을 정렬된 순서로 나열합니다:
e <- new.env()
for (fruit in c("pear", "apple")) assign(fruit, nchar(fruit), envir = e)
print(ls(e))
print(get("pear", envir = e))
print(exists("kiwi", envir = e))출력:
[1] "apple" "pear"
[1] 4
[1] FALSE참조 의미론을 가진 환경은 S3 객체입니다. 해당 환경의 메서드는 평소처럼 작동하며, 환경을 변경하는 함수는 환경 자체를 직접 변경합니다:
new_wallet <- function(coins = 0) {
w <- new.env()
w$coins <- coins
class(w) <- "wallet"
w
}
print.wallet <- function(x, ...) {
cat("wallet with", x$coins, "coins\n")
invisible(x)
}
spend <- function(w, n) w$coins <- w$coins - n
w <- new_wallet(10)
spend(w, 3)
w출력:
wallet with 7 coins챌린지
쉬움재고는 하나의 변수인 items를 가진 inventory 클래스의 환경이며, items는 재고를 나타내는 이름이 지정된 숫자 벡터입니다. Inventory.R을 완성하세요:
new_inventory()는 비어 있는items(c()로 충분함)와 클래스를 가진 환경을 생성합니다.add_stock(inv, item, n)은 품목의 재고에n을 더하며, 새 품목의 경우 0부터 시작합니다.take_stock(inv, item, n)은 재고가 충분하면n을 차감하고TRUE를 반환하며, 그렇지 않으면 아무것도 변경하지 않고FALSE를 반환합니다.stock_of(inv, item)은 재고를 반환하며, 알 수 없는 품목의 경우 0을 반환합니다.
함수는 재고를 제자리에서 변경하며 재고 자체를 반환하지 않습니다. 제공된 코드는 add apple 5 및 take apple 2 명령을 읽고, 각 take의 결과를 출력한 다음 모든 품목을 알파벳순으로 출력합니다.
작성한 코드는 Inventory.R에 넣으세요. main.R에는 제공된 입력/출력 코드가 들어 있으며 편집할 수 없습니다.
직접 해보기
source("Inventory.R")
# 제공된 입력/출력 코드: 그대로 유지하세요
input <- suppressWarnings(readLines(file("stdin")))
inv <- new_inventory()
for (line in input) {
p <- strsplit(line, " ")[[1]]
n <- as.numeric(p[3])
if (p[1] == "add") add_stock(inv, p[2], n)
if (p[1] == "take") cat("take ", p[2], ": ", if (take_stock(inv, p[2], n)) "ok" else "not enough", "\n", sep = "")
}
for (item in sort(names(inv$items))) cat(item, ": ", stock_of(inv, item), "\n", sep = "")
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
객체 지향 프로그래밍의 모든 레슨
직접 연습해 보세요: 온라인 R 컴파일러