Môi trường dưới dạng đối tượng
Thuộc phần Lập trình hướng đối tượng trong hành trình R của Coddy. Bài học 18 trên 57.
Môi trường là một tập hợp các giá trị có tên, giống như danh sách, được tạo bằng new.env(). Điểm khác biệt là môi trường không bao giờ được sao chép: mọi biến tham chiếu đến nó đều thấy cùng một đối tượng, vì vậy thay đổi qua một tên sẽ hiển thị qua tất cả các tên đó:
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)Đầu ra:
[1] 99
[1] 1Một hàm nhận một môi trường sẽ thay đổi đối tượng của bên gọi. Hàm không cần trả về gì, và bên gọi không gán kết quả:
deposit <- function(acc, x) acc$balance <- acc$balance + x
acc <- new.env()
acc$balance <- 10
deposit(acc, 5)
deposit(acc, 5)
print(acc$balance)Đầu ra:
[1] 20assign(), get() và exists() làm việc với tên được lưu trong một biến, còn ls() liệt kê tên trong môi trường theo thứ tự đã sắp xếp:
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))Đầu ra:
[1] "apple" "pear"
[1] 4
[1] FALSEMôi trường có thuộc tính lớp là một đối tượng S3 có ngữ nghĩa tham chiếu: các phương thức của nó hoạt động như thường lệ, còn các hàm thay đổi nó sẽ thay đổi trực tiếp tại chỗ:
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Đầu ra:
wallet with 7 coinsThử thách
DễKho hàng là một môi trường thuộc lớp inventory, có một biến items, là một vector số có tên lưu số lượng hàng. Hoàn thành Inventory.R:
new_inventory()tạo môi trường vớiitemstrống (c()là được) và lớp.add_stock(inv, item, n)thêmnvào số lượng hàng của mặt hàng, bắt đầu từ 0 nếu là mặt hàng mới.take_stock(inv, item, n)lấy đinvà trả vềTRUEkhi có đủ hàng, nếu không thì không thay đổi gì và trả vềFALSE.stock_of(inv, item)trả về số lượng hàng, bằng 0 nếu không biết mặt hàng đó.
Các hàm thay đổi kho hàng tại chỗ và không trả về kho. Đoạn code được cung cấp đọc các lệnh add apple 5 và take apple 2, in kết quả của từng lệnh take, rồi in mọi mặt hàng theo thứ tự bảng chữ cái.
Đặt code của bạn trong Inventory.R. main.R chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
source("Inventory.R")
# Đoạn code đầu vào/đầu ra đã cho: giữ nguyên
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 = "")
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Kiến thức cơ bản về S3
Làm việc với tệpDanh sách với một lớpHàm khởi tạoPhương thức in ra và định dạngTrình xác thực và hàm hỗ trợÔn tập: nhiệt độ4Tính đóng gói trong R
Closure dưới dạng đối tượngMôi trường dưới dạng đối tượngHàm truy cậpBảo vệ trạng tháiÔn tập: đồng hồ tính phí đỗ xe2S3, hàm generic và phương thức
Hàm generic và UseMethodPhương thức mặc địnhPhương thức cho hàm generic cơ sởCơ bản về NextMethodÔn tập: diện tích hình5Các lớp S4
Định nghĩa lớp S4Slot và quyền truy cậpKiểm tra tính hợp lệPhương thức showÔn tập: Danh mục sản phẩmTự luyện tập: Trình biên dịch R online