分配替换非本地列表中的值

[[< - 在非本地对象上使用时对列表和环境的行为不同:

lst = list()
env = new.env()

(function () lst[['x']] = 1)()
(function () env[['x']] = 1)()
lst
# list()

as.list(env)
# $x
# [1] 1

换句话说,如果[[< - 是环境,它修改(非本地))环境的目标,但如果它是向量/列表,则它创建一个新的本地对象。 我想知道两件事情:
>为什么行为差异?
>有没有一种实现与环境相同的结果的方法,而不使用< - ?
关于(1),我知道列表和环境之间的多重差异(特别是我知道环境不被复制),但文档没有提到为什么[[< - 两者之间不同 - 特别是为什么运算符将在不同的范围上操作。这是一个bug吗?至少是反直觉的,需要一些不平凡的实施shenanigans 关于(2),明显的解决方案当然是使用< - :

(function () lst[['x']] <<- 1)()

但是,我更倾向于理解差异,而不仅仅是在周围工作。此外,我迄今为止使用了assign而不是< - ,我更喜欢这个,因为它允许我更好地控制赋值的范围(特别是因为我可以指定inherits = FALSE。< - 是我的味道太多了巫毒 然而,上述不能解决(据我所知)使用assign,因为assign只适用于环境,而不是列表。特别地,在assign(‘x’,1,env)工作(并且与上述相同)时,assign(‘x’,1,lst)不起作用。 1
为了详细说明,当然期望R对于使用动态调度(例如通过S3)的不同对象类型来做不同的事情。但是,这不是这种情况(至少不是直接的):在分配目标的对象类型已知之前发生范围分辨率的区别 – 否则上述操作将在全局lst上运行,而不是创建新的本地对象。所以在内部[[< - 必须等同于:

`[[<-` = function (x, i, value) {
    if (exists(x, mode = 'environment', inherits = TRUE))
        assign(i, value, pos = x, inherits = FALSE)
    else if (exists(x, inherits = FALSE)
        internal_assign(x, i, value)
    else
        assign(x, list(i = value), pos = parent.frame(), inherits = FALSE)
}
R-language definition(2.1.10节)说:

Unlike most other R objects, environments are not copied when passed
to functions or used in assignments.

“6.3更多关于评估”也给出了一个稍微相关的提示:

Notice that evaluation in a given environment may actually change that
environment, most obviously in cases involving the assignment
operator, such as

06000

This is also true when evaluating in lists, but the original list does
not change because one is really working on a copy.

所以,你的第一个问题的答案是列表需要被复制分配给它们,但环境可以被修改(这对性能有很大的影响)。

关于你的第二个问题:

如果您正在使用列表,则唯一的选择似乎是

>将列表复制到本地范围(使用get),
>分配到列表中,
>使用assign将修改的列表复制回原始环境。

http://stackoverflow.com/questions/31476340/assignment-to-replace-value-in-nonlocal-list

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:分配替换非本地列表中的值