R 如何将参数(名称)传递给函数工厂?

R 如何将参数(名称)传递给函数工厂?,r,functional-programming,closures,factory,R,Functional Programming,Closures,Factory,我需要用很多不同的参数构建很多函数,尽管它们共享很多代码和结构。 为了避免重复,我想我应该聪明一点,自己建立一个函数工厂(又名闭包) 我不知道如何在函数工厂中传递函数参数 我的用例是一组S3构造函数,它们共享相同的验证机制。 所以我会用这个例子来解释我的问题 比如说,我有一个ClassA和ClassB,它们在各自的构造函数中都需要自己的参数: ClassA <- function(A_arg1, A_arg2) { # some class-SPECIFIC construction

我需要用很多不同的参数构建很多函数,尽管它们共享很多代码和结构。 为了避免重复,我想我应该聪明一点,自己建立一个函数工厂(又名闭包)

我不知道如何在函数工厂中传递函数参数

我的用例是一组S3构造函数,它们共享相同的验证机制。 所以我会用这个例子来解释我的问题

比如说,我有一个
ClassA
ClassB
,它们在各自的构造函数中都需要自己的参数:

ClassA <- function(A_arg1, A_arg2) {
  # some class-SPECIFIC construction magic happens, say
  out <- list(A_arg1, A_arg2)

  # some GENERAL construction magic happens
  class(out) <- "ClassA"

  return(out)
}

ClassB <- function(B_arg1, B_arg2) {
  # some class-SPECIFIC construction magic happens, say
  out <- B_arg1 + B_arg2

  # some GENERAL construction magic happens
  class(out) <- "ClassB"

  return(out)
}
但是,这不起作用,因为生成的构造函数只有一个
类特定的\u参数
-参数,而不是实际的
a\u arg1
a\u arg2

有办法做到这一点吗? 我做错了吗

(对我来说,生成的类构造函数具有正确命名的参数非常重要,因此,
方法无法工作)。

以下是我的尝试:

produce_class_constructor <- function(classname, fun) {
  out_fun <- function() {
    out_obj <- do.call(fun, as.list(environment()))
    class(out_obj) <- classname
    out_obj
  }
  formals(out_fun) <- formals(fun)
  out_fun
}

ClassA <- produce_class_constructor(classname = "ClassA", 
  fun = function(A_arg1, A_arg2) {list(A_arg1, A_arg2)})
ClassA(1, 2)
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
#
#attr(,"class")
#[1] "ClassA"

ClassB <- produce_class_constructor(classname = "ClassB", 
  fun = function(B_arg1, B_arg2) {B_arg1 + B_arg2})
ClassB(B_arg2 = 2, 1)
#[1] 3
#attr(,"class")
#[1] "ClassB"

product\u class\u构造函数啊,太棒了,非常感谢,这就完成了工作。你@tonytonov或其他人知道为什么这被认为是“危险的”和/或有其他更安全的建议来完成这件事吗?@Maxhold不客气。嗯,到目前为止还不是非常危险,但关键是,弄乱
body
formals
不是一件小事。很难看:下周给我看这个片段,我可能不明白它的目的。它很难维护,并且您可能会在以后的开发阶段遇到一些怪癖(比如,如果您需要
构造函数支持等,则需要额外的工作)。这并不意味着这条路不好;对于像您这样的任务,这很好,只是不要尝试实现您自己的完全面向对象的类系统:)我添加了一个类似的问题,我试图找出如何实现无点函数编程。也许更优雅。
produce_class_constructor <- function(classname, fun) {
  class_specific_arguments <- formals(fun = fun)  # this works just fine on the console
  construct_class <- function(class_specific_arguments) {
    # here runs the class-specific stuff
    out <- fun(class_specific_arguments)

    # here runs the general stuff
    class(out) <- classname
  }
}
produce_class_constructor <- function(classname, fun) {
  out_fun <- function() {
    out_obj <- do.call(fun, as.list(environment()))
    class(out_obj) <- classname
    out_obj
  }
  formals(out_fun) <- formals(fun)
  out_fun
}

ClassA <- produce_class_constructor(classname = "ClassA", 
  fun = function(A_arg1, A_arg2) {list(A_arg1, A_arg2)})
ClassA(1, 2)
#[[1]]
#[1] 1
#
#[[2]]
#[1] 2
#
#attr(,"class")
#[1] "ClassA"

ClassB <- produce_class_constructor(classname = "ClassB", 
  fun = function(B_arg1, B_arg2) {B_arg1 + B_arg2})
ClassB(B_arg2 = 2, 1)
#[1] 3
#attr(,"class")
#[1] "ClassB"