[R如何解释论点:arg.list <- list(x, y)
在功能下面的定义,它复制x
和y
到arg.list
对象时执行发生,或者它们是通过引用传递?基础路过R中的功能
fplot <- function(x, y, add=FALSE){
arg.list <- list(x, y)
if(!add){
plot(arg.list))
}else{
lines(arg.list)
}
}
[R如何解释论点:arg.list <- list(x, y)
在功能下面的定义,它复制x
和y
到arg.list
对象时执行发生,或者它们是通过引用传递?基础路过R中的功能
fplot <- function(x, y, add=FALSE){
arg.list <- list(x, y)
if(!add){
plot(arg.list))
}else{
lines(arg.list)
}
}
变量通过引用嵌入到列表中(至少在使用向量时)。
证明:
library(pryr)
x <- 1:100
y <- 201:200
arg.list <- list(x,y)
al.x <- arg.list[[1]]
al.y <- arg.list[[2]]
现在看看内存地址(它们是相同的):
> address(x)
[1] "0x37598c0"
> address(y)
[1] "0x40fd6f8"
> address(al.x)
[1] "0x37598c0"
> address(al.y)
[1] "0x40fd6f8"
如果更改一个项目副本将被创建(“关于修改本”) :
> x[1]=42
> address(x)
[1] "0x417a470"
> al.x <- arg.list[[1]]
> address(al.x)
[1] "0x37598c0"
编辑:
作为@HongOoi说:R语义上从不使用引用(环境类中的对象除外),但复制变量。它“足够聪明,以避免复制,直到他们真正需要”(“复制[第一]修改”)。函数参数在语义上“按值”传递(即使引用被使用直到修改发生)。
R的语义是函数参数总是按值传递。底层实现可能不一定会创建新的参数副本,以节省内存。但是你的功能就像拥有全新的拷贝一样工作。
这意味着你不必担心改变功能之外的变量,因为你的内心改变了它:
x <- 1
f <- function(z) {
z <- z + 1
z
}
y <- f(x)
print(y) # y now contains 2
print(x) # but x still contains 1
若R是传递的引用,然后修改的f
的说法也将修改传入的变量。这不会发生。
那么R尤达的答案呢? – Qbik
尤达的答案是关于R的内部。它足够聪明,除非需要,否则不要复制一个参数。例如,如果我的函数'f'完全不修改它的参数:'f < - function(z){return(z + 1)}'那么它就不会再为'z'创建一个新副本。然而,如果参数的新副本被创建,'f'的外部行为总是_as。 –
有一些地区,R是通过参考,即环境。我可能会在后面添加这个答案。 –
请注意,您当前的问题与传递给函数的参数无关(如标题所示),而是从标量向量变量构造容器变量......这真的是您的意图吗? –
@R尤达,在我的实际函数中,'x'和'y'是'data.frame',然后我使用它们:'x $ var1' – Qbik
如果在外部或内部修改x和y,该功能(直到此时“第一次修改时复制”仍为真,以避免不必要的存储器复制)。 'x $ var'产生一个向量...... –