Menu
CoddyTech

Списки с классом

Часть раздела Объектно-ориентированное программирование путешествия по R на Coddy. Урок 2 из 57.

S3 — самая старая и наиболее используемая система объектов в R. Объект S3 — это обычный список с атрибутом class, меткой, которая указывает, что это за тип объекта. class(x) <- "dog" задаёт метку:

rex <- list(name = "Rex", age = 3)
class(rex) <- "dog"
print(class(rex))
cat(rex$name, "is", rex$age)

Вывод:

[1] "dog"
Rex is 3

structure() создает значение и задает его атрибуты одним вызовом — это обычный способ создания объекта S3. Поля считываются с помощью $, как и в любом списке:

rex <- structure(list(name = "Rex", age = 3), class = "dog")
print(class(rex))
print(is.list(rex))
print(rex$age)

Вывод:

[1] "dog"
[1] TRUE
[1] 3

Класс — это лишь метка: R не проверяет, какие поля есть у объекта, поэтому любой список можно назвать dog. unclass() удаляет метку и возвращает обычный список:

p <- structure(list(x = 1, y = 2), class = "point")
print(unclass(p))

Вывод:

$x
[1] 1

$y
[1] 2

Объекты S3 — это значения. Функция, изменяющая объект, изменяет его собственную копию, поэтому возвращает новую версию, а вызывающий код присваивает её. Исходный объект остаётся прежним:

birthday <- function(d) {
  d$age <- d$age + 1
  d
}
rex <- structure(list(name = "Rex", age = 3), class = "dog")
older <- birthday(rex)
cat(rex$age, older$age)

Вывод:

3 4
challenge icon

Задание

Легко

Завершите make_pet(name, species, age) в Pet.R. Она возвращает список с полями name, species и age в этом порядке и классом pet. Затем завершите describe_pet(p), которая возвращает одно предложение: для питомца по имени Rex, вида dog и возраста 3 получается Rex is a 3 year old dog.

Предоставленный код считывает имя, вид и возраст, создаёт питомца и выводит его класс, имена его полей и предложение.

Ваш код должен быть в Pet.R. В main.R находится предоставленный код ввода/вывода, который нельзя редактировать.

Попробуйте сами

source("Pet.R")

# Предоставленный код ввода/вывода: оставьте его без изменений
input <- suppressWarnings(readLines(file("stdin")))
p <- make_pet(input[1], input[2], as.numeric(input[3]))
cat("class: ", class(p), "\n", sep = "")
cat("fields: ", paste(names(p), collapse = ", "), "\n", sep = "")
cat(describe_pet(p), "\n", sep = "")
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Объектно-ориентированное программирование

Потренируйтесь самостоятельно: Онлайн-компилятор R