如何在下面的函数定义中解释行:arg.list <- list(x, y)
,是否在执行发生时将x
和y
复制到arg.list
对象中,或者它们是通过引用传递的?
fplot <- function(x, y, add=FALSE){
arg.list <- list(x, y)
if(!add){
plot(arg.list))
}else{
lines(arg.list)
}
}
答案 0 :(得分:2)
变量通过引用嵌入到列表中(至少如果使用向量)。
证明:
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"
如果您更改了一个项目,则会创建一个副本(&#34;复制时修改&#34;):
> x[1]=42
> address(x)
[1] "0x417a470"
> al.x <- arg.list[[1]]
> address(al.x)
[1] "0x37598c0"
修改强>
正如@HongOoi所说:R语义上从不使用引用(环境类中的对象除外),而是复制变量。它非常聪明,可以避免复制,直到真正需要它们为止#34; (&#34;复制[第一次]修改&#34;)。函数参数通过值&#34;传递。语义上(即使在修改发生之前使用引用)。
答案 1 :(得分: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
的参数也会修改传入的变量。这不会发生。