返回功能列表,这被认为是OOP吗?

Lyt*_*tze 6 r

我很久以前就在Coursera的约翰霍普金斯MOOC R编程中学到了这种方法.我们的想法是返回父函数范围中定义的函数列表.例如:

newString <- function(s) {
    l <- nchar(s)
    return(list(
        get = function() return(s),
        len = function() return(l),
        concate = function(cat) {
            s <<- paste0(s, cat)
            l <<- nchar(s)
        },
        find = function(pattern) return(grepl(pattern, s)),
        substitute = function(pattern, sub) {
            s <<- gsub(pattern, sub, s)
            l <<- nchar(s)
        }
    ))
}
Run Code Online (Sandbox Code Playgroud)

此函数返回可以操作项"s"的函数/方法列表.我可以"新"这个"对象"调用父函数:

my <- newString("hellow")
Run Code Online (Sandbox Code Playgroud)

并使用$看起来像OOP 的"方法" .

my$get()
# [1] "hellow"
my$len()
# [1] 6
my$substitute("w$", "")
my$get()
# [1] "hello"
my$len()
# [1] 5
my$concate(", world")
my$get()
# [1] "hello, world"
my$find("world$")
# [1] TRUE
Run Code Online (Sandbox Code Playgroud)

要直接打印"对象",我们可以看到它是一个函数列表.并且所有这些功能都位于同一环境中0x103ca6e08,该项目s也在其中.

my
# $get
# function () 
#     return(s)
# <bytecode: 0x1099ac1e0>
#     <environment: 0x103ca6e08>
#     
# $len
# function () 
#     return(l)
# <bytecode: 0x109a58058>
#     <environment: 0x103ca6e08>
#     
# $concate
# function (cat) 
# {
#     s <<- paste0(s, cat)
#     l <<- nchar(s)
# }
# <bytecode: 0x1074fd4e8>
#     <environment: 0x103ca6e08>
#     
# $find
# function (pattern) 
#     return(grepl(pattern, s))
# <bytecode: 0x1076c8470>
#     <environment: 0x103ca6e08>
#     
# $substitute
# function (pattern, sub) 
# {
#     s <<- gsub(pattern, sub, s)
#     l <<- nchar(s)
# }
# <bytecode: 0x1077ad270>
#     <environment: 0x103ca6e08>
Run Code Online (Sandbox Code Playgroud)

那么这种编程风格(?)被认为是OOP还是OOP?这与S3/S4的区别是什么?


感谢@ G.Grothendieck,@ r2evans和@Jozef.scopingR中的演示文档说"函数可以封装状态信息",因为R中的作用域规则和RC系统"使用环境",所以我认为我所做的与原始RC系统类似.


"对象是带有函数的数据.闭包是一个带数据的函数." - 约翰D.库克

闭包得到它们的名字,因为它们包含父函数的环境并且可以访问它的所有变量.

http://adv-r.had.co.nz/Functional-programming.html#closures中,我发现最合适的名称是封闭.

Joz*_*zef 4

你在这里尝试做的事情让我想起了包reference classes的概念的替代实现R6- 本质上是试图创建一个类似于其他“经典”OOP 语言(例如 Java)的 OO 系统:

参考类:

R6

例如,您可以像这样定义 R6 类:

library(R6)

Person <- R6Class("Person",
  public = list(
    name = NULL,
    hair = NULL,
    initialize = function(name = NA, hair = NA) {
      self$name <- name
      self$hair <- hair
      self$greet()
    },
    set_hair = function(val) {
      self$hair <- val
    },
    greet = function() {
      cat(paste0("Hello, my name is ", self$name, ".\n"))
    }
  )
)
Run Code Online (Sandbox Code Playgroud)

然后可以从该类创建一个实例:

ann <- Person$new("Ann", "black")
Run Code Online (Sandbox Code Playgroud)

快速介绍: https: //r6.r-lib.org/articles/Introduction.html