Menu
Coddy logo textTech

접근자 함수

Coddy R 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨. 57개 중 19번째.

캡슐화란 다른 코드가 객체의 필드에 직접 접근하는 대신 함수를 통해 객체와 상호 작용하도록 하는 것을 의미합니다. 게터는 값을 읽고 세터는 값을 변경합니다. S3 리스트의 경우 세터는 변경된 복사본을 반환합니다:

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))

출력:

[1] "Ada Lovelace"

접근자를 사용하면 객체를 사용하는 코드를 손상시키지 않고 객체가 데이터를 저장하는 방식을 변경할 수 있습니다. 이 온도계는 섭씨를 저장하고, 요청을 받으면 getter가 화씨를 계산하므로 호출자는 필드 자체를 보지 못합니다:

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))

출력:

25 77

R의 고유 세터인 names(x) <- ...와 같은 함수는 대체 함수입니다. x와 value 매개변수를 받는 "name<-"이라는 함수가 있으면 호출자는 name(p) <- "Bo"라고 작성할 수 있습니다. R은 이 함수를 호출하고 그 결과를 다시 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))

출력:

[1] "Bo"

클로저 객체의 getter는 비공개 데이터의 복사본을 반환합니다. 그 복사본을 변경해도 객체는 변경되지 않으므로, 객체에 접근할 수 있는 유일한 방법은 객체 자체의 함수를 통하는 것입니다:

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())

출력:

[1] "milk"
challenge icon

챌린지

쉬움

contact는 name 및 email 필드를 가진 contact 클래스의 S3 리스트입니다. Contact.R을 완성하세요:

  • new_contact(name, email)은 이메일을 공백을 제거하고 소문자로 변환하여 저장합니다.
  • getter인 contact_name(x) 및 contact_email(x)을 구현합니다.
  • 대체 함수 "contact_email<-"은 새 이메일을 공백을 제거하고 소문자로 변환하여 저장하므로, 호출자는 contact_email(c1) <- value와 같이 작성할 수 있습니다.

제공된 코드는 name,email을 읽은 다음 새 이메일을 읽고, 변경할 때마다 Ada <ada@x.com>을 출력하며 마지막에 저장된 필드 이름을 출력합니다.

코드는 Contact.R에 작성하세요. main.R에는 제공된 입력/출력 코드가 들어 있으며 편집할 수 없습니다.

직접 해보기

source("Contact.R")

# 제공된 입력/출력 코드: 그대로 유지하세요
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 icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

객체 지향 프로그래밍의 모든 레슨

직접 연습해 보세요: 온라인 R 컴파일러