您可以使用pryr::promise_info(l)$env 来完成此操作,但这是一件非常不像 R 的事情。函数不应该有副作用。
例如,
pop <- function(l) {
info <- pryr::promise_info(l)
if (!is.name(info$code))
stop("Argument expression should be a name.")
result <- l[[1]] # work on lists too
assign(as.character(info$code), l[-1], envir = info$env)
result
}
l <- c(1, 3, 5)
pop(l)
#> Registered S3 method overwritten by 'pryr':
#> method from
#> print.bytes Rcpp
#> [1] 1
l
#> [1] 3 5
由reprex package (v0.3.0) 于 2020-08-15 创建
编辑添加:有趣的是,到目前为止,三个答案中没有一个适用于像这样的复杂情况:
f <- function(x) {
cat("The pop(x) result is", pop(x), "\n")
cat("Now x is ", x, "\n")
cat("Now l is ", l, "\n")
}
l <- c(1, 3, 5)
f(l)
@RuiBarradas 的回答给出了
The pop(x) result is 5
Now x is 1 3 5
Now l is 1 3 5
(他弹出最后一个值而不是第一个值,这没什么大不了,但x和l都没有被修改。)
@AllanCameron 的回答给出了
The pop(x) result is 1
Now x is 3 5
Now l is 1 3 5
这可以说是正确的(x 被弹出),但我认为 l 被弹出会很好,但这似乎很棘手。
我的回答随着这条消息而死:
Error in pop(x) : Argument expression should be a name.
这似乎是一个错误:显然无论是 x 还是 l,它确实是一个名称。问题似乎出在pryr::promise_info 中,它返回的编译代码将返回x 的值,而不仅仅是x 的代码。如果我通过compiler::enableJIT(0) 关闭 JIT 编译,我会得到与@AllanCameron 相同的结果。我不清楚如何放松适当的数量以弹出l 而不仅仅是x。