【发布时间】:2018-07-24 18:03:43
【问题描述】:
我想在我的泛型中设置一些标志(在调用UseMethod(),我知道很多:)),然后在方法中使用和/或更新这些标志。
像这样:
g <- function(x) {
y <- 10
UseMethod("g")
}
g.default <- function(x) {
c(x = x, y = y)
}
g.a <- function(x) {
y <- 5 # update y from generic here
NextMethod()
}
这在直接跳转到默认方法时有效:
g(structure(.Data = 1, class = "c")) # here y is never updated
# x y
# 1 10
但是当我通过NextMethod()时,y神秘地消失了:
g(structure(.Data = 1, class = "a")) # here y is updated, but cannot be found
# Error in g.default(structure(.Data = 1, class = "a")) :
# object 'y' not found
我已经想出了如何解决这个问题,只是通过y 转了很多次:
f <- function(x, ...) {
y <- 10
UseMethod("f")
}
f.default <- function(x, ..., y = 3) {
c(x = x, y = y)
}
f.a <- function(x, ...) {
y <- 5
NextMethod(y = y)
}
产生
f(structure(.Data = 1, class = "c"))
# x y
# 1 3
f(structure(.Data = 1, class = "a"))
# x y
# 1 5
我的问题是:为什么上面的g().*-example 中的NextMethod() 会杀死额外的y 参数?
我认为UseMethod() 和NextMethod() 的全部意义在于将所有对象从一个调用传递到另一个调用, 不必手动传递它们:
NextMethod 通过为下一个方法创建一个特殊的调用框架来工作。如果没有提供新参数,则参数的数量、顺序和名称将与当前方法的参数相同,但它们的值将被承诺在当前方法和环境中评估它们的名称。
我特别困惑UseMethod() 似乎确实传递了y,但NextMethod() 没有。
【问题讨论】:
-
与关于
UseMethod的段落相反,引用并没有说传递了局部变量。它仅指参数,更具体地说是关于它们作为承诺传递。传递局部变量可能会降低性能并且是不寻常的(为什么需要这样做?)。没有被杀死;函数环境的内容根本就不传了。 -
明确说明要传递给函数的内容总是更好,因此您的解决方案对我来说似乎很好。
-
我的心智模型是泛型正在做调度的工作。然后,该方法向泛型发出信号,告知其邻居将完成工作。从这个角度来看,这并不矛盾(尽管实际情况并非如此)。
-
我认为关键可能在于“
NextMethod通过为下一个方法创建一个特殊的调用框架来工作”。UseMethod将泛型调用为调用环境,因此其变量位于搜索路径上,但NextMethod显然正在创建某种单独的环境。我想? -
例如这是
(function(){x = 5; (function() x)()})()和(function(){x = 5; eval(expression((function() x)()), envir = globalenv())})()之间的区别
标签: r oop inheritance class-method