1

[R如何解释论点:arg.list <- list(x, y)在功能下面的定义,它复制xyarg.list对象时执行发生,或者它们是通过引用传递?基础路过R中的功能

fplot <- function(x, y, add=FALSE){ 
    arg.list <- list(x, y) 
    if(!add){ 
    plot(arg.list)) 
    }else{ 
    lines(arg.list) 
    } 
} 
+0

请注意,您当前的问题与传递给函数的参数无关(如标题所示),而是从标量向量变量构造容器变量......这真的是您的意图吗? –

+0

@R尤达,在我的实际函数中,'x'和'y'是'data.frame',然后我使用它们:'x $ var1' – Qbik

+0

如果在外部或内部修改x和y,该功能(直到此时“第一次修改时复制”仍为真,以避免不必要的存储器复制)。 'x $ var'产生一个向量...... –

回答

3

变量通过引用嵌入到列表中(至少在使用向量时)。

证明:

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语义上从不使用引用(环境类中的对象除外),但复制变量。它“足够聪明,以避免复制,直到他们真正需要”(“复制[第一]修改”)。函数参数在语义上“按值”传递(即使引用被使用直到修改发生)。

2

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的说法也将修改传入的变量。这不会发生。

+0

那么R尤达的答案呢? – Qbik

+0

尤达的答案是关于R的内部。它足够聪明,除非需要,否则不要复制一个参数。例如,如果我的函数'f'完全不修改它的参数:'f < - function(z){return(z + 1)}'那么它就不会再为'z'创建一个新副本。然而,如果参数的新副本被创建,'f'的外部行为总是_as。 –

+0

有一些地区,R是通过参考,即环境。我可能会在后面添加这个答案。 –