Menu
Coddy logo textTech

Funkcje dostępowe

Część sekcji Programowanie obiektowe ścieżki R w Coddy. Lekcja 19 z 57.

Hermetyzacja oznacza, że inny kod współpracuje z obiektem za pomocą funkcji, zamiast odwoływać się bezpośrednio do jego pól. Getter odczytuje wartość, a setter ją zmienia. W przypadku listy S3 setter zwraca zmienioną kopię:

new_member <- function(name) structure(list(name = name), class = "member")
get_name <- function(p) p$name
set_name <- function(p, value) {
  p$name <- value
  p
}
p <- new_member("ada")
p <- set_name(p, "Ada Lovelace")
print(get_name(p))

Wynik:

[1] "Ada Lovelace"

Akcesory pozwalają obiektowi zmieniać sposób przechowywania danych bez psucia kodu, który z niego korzysta. Ten termometr przechowuje temperaturę w stopniach Celsjusza, a funkcja pobierająca oblicza stopnie Fahrenheita na żądanie, więc kod wywołujący nigdy nie widzi samego pola:

new_thermo <- function(c) structure(list(c = c), class = "thermo")
celsius <- function(t) t$c
fahrenheit <- function(t) t$c * 9 / 5 + 32
t <- new_thermo(25)
cat(celsius(t), fahrenheit(t))

Wynik:

25 77

Własne metody ustawiające w R, takie jak names(x) <- ..., to funkcje zastępujące. Funkcja o nazwie "name<-" z parametrami x i value pozwala wywołującym zapisać name(p) <- "Bo"; R wywołuje ją i przypisuje wynik z powrotem do p:

new_member <- function(name) structure(list(name = name), class = "member")
name <- function(p) p$name
"name<-" <- function(x, value) {
  x$name <- trimws(value)
  x
}
p <- new_member("ada")
name(p) <- "  Bo  "
print(name(p))

Wynik:

[1] "Bo"

Getter obiektu domknięcia zwraca kopię prywatnych danych. Zmiana tej kopii nie zmienia obiektu, więc jedynym sposobem dostępu do niego jest użycie jego własnych funkcji:

make_list <- function() {
  items <- character(0)
  list(add = function(x) items <<- c(items, x),
       get_items = function() items)
}
todo <- make_list()
todo$add("milk")
mine <- todo$get_items()
mine[1] <- "HACKED"
print(todo$get_items())

Wynik:

[1] "milk"
challenge icon

Wyzwanie

Łatwy

Kontakt to lista S3 klasy contact z polami name i email. Uzupełnij Contact.R:

  • new_contact(name, email) przechowuje adres e-mail bez białych znaków na początku i końcu oraz zapisany małymi literami.
  • Funkcje pobierające contact_name(x) i contact_email(x).
  • Funkcja zastępująca "contact_email<-", która przechowuje nowy adres e-mail bez białych znaków na początku i końcu oraz zapisany małymi literami, dzięki czemu wywołujący mogą użyć zapisu contact_email(c1) <- value.

Dostarczony kod odczytuje name,email, a następnie nowe adresy e-mail, i po każdej zmianie wypisuje Ada <ada@x.com>, a na końcu zapisane nazwy pól.

Twój kod umieść w Contact.R. Plik main.R zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.

Spróbuj swoich sił

source("Contact.R")

# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
input <- suppressWarnings(readLines(file("stdin")))
p <- strsplit(input[1], ",")[[1]]
c1 <- new_contact(p[1], p[2])
cat(contact_name(c1), " <", contact_email(c1), ">\n", sep = "")
for (value in input[-1]) {
  contact_email(c1) <- value
  cat(contact_name(c1), " <", contact_email(c1), ">\n", sep = "")
}
cat("stored fields: ", paste(names(unclass(c1)), collapse = ", "), "\n", sep = "")
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator R online