Menu
CoddyTech

Phương thức in ra và định dạ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 4 trên 57.

Khi in ra một giá trị, R gọi hàm (function) print(). Nếu không có gì đặc biệt dành cho lớp này, đối tượng S3 sẽ được in dưới dạng danh sách, theo sau là thuộc tính lớp, khiến nội dung khó đọc:

m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
print(m)

Đầu ra:

$amount
[1] 9.5

$currency
[1] "EUR"

attr(,"class")
[1] "money"

Một phương thức (method) là một hàm có tên generic.class. Khi print() nhận một đối tượng thuộc lớp money, nó sẽ tìm print.money() và gọi hàm đó thay thế. Một phương thức print in nội dung bằng cat() và kết thúc bằng invisible(x), nhờ vậy nó trả về đối tượng mà không in thêm lần nữa:

print.money <- function(x, ...) {
  cat("<money ", x$amount, " ", x$currency, ">\n", sep = "")
  invisible(x)
}
m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
print(m)
m

Đầu ra:

<money 9.5 EUR>
<money 9.5 EUR>

format() là cách tổng quát để chuyển một giá trị thành văn bản. Phương thức format.money() trả về văn bản thay vì in ra, nhờ đó đoạn code khác có thể đưa văn bản đó vào một câu, còn phương thức print có thể dùng lại văn bản:

format.money <- function(x, ...) {
  sprintf("%.2f %s", x$amount, x$currency)
}
print.money <- function(x, ...) {
  cat("Money:", format(x), "\n")
  invisible(x)
}
m <- structure(list(amount = 9.5, currency = "EUR"), class = "money")
m
cat("You owe", format(m), "\n")

Đầu ra:

Money: 9.50 EUR 
You owe 9.50 EUR 

Một phương thức nhận cùng các đối số như hàm tổng quát của nó. print() và format() được khai báo là function(x, ...), vì vậy các phương thức của chúng cũng bắt đầu bằng x, .... ... nhận các đối số bổ sung như digits mà bên gọi có thể truyền vào. Các phương thức hoạt động ở bất cứ đâu hàm tổng quát được gọi, chẳng hạn như bên trong vapply():

format.money <- function(x, ...) sprintf("%.2f %s", x$amount, x$currency)
wallet <- list(
  structure(list(amount = 3, currency = "EUR"), class = "money"),
  structure(list(amount = 0.5, currency = "USD"), class = "money")
)
print(vapply(wallet, format, character(1)))

Đầu ra:

[1] "3.00 EUR" "0.50 USD"
challenge icon

Thử thách

Dễ

Đã có new_money() trong Money.R. Thêm hai phương thức vào cùng tệp:

  • format.money(x, ...) trả về số tiền với hai chữ số thập phân và đơn vị tiền tệ: 9.50 EUR.
  • print.money(x, ...) in <money 9.50 EUR> trên một dòng riêng, dùng format(), rồi trả về invisible(x).

Đoạn code được cung cấp đọc các dòng 9.5 EUR, in ra từng đối tượng tiền, rồi in ra list: cùng tất cả số tiền đã định dạng, nối với nhau bằng + .

Viết code trong Money.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("Money.R")

# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input <- suppressWarnings(readLines(file("stdin")))
all <- list()
for (line in input) {
  p <- strsplit(line, " ")[[1]]
  m <- new_money(as.numeric(p[1]), p[2])
  print(m)
  all[[length(all) + 1]] <- m
}
cat("list: ", paste(vapply(all, format, character(1)), collapse = " + "), "\n", sep = "")
quiz iconTự kiểm tra

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

Tự luyện tập: Trình biên dịch R online