R函数中参数传递的基础知识

时间:2017-01-22 16:27:21

标签: r functional-programming parameter-passing pass-by-reference

如何在下面的函数定义中解释行:arg.list <- list(x, y),是否在执行发生时将xy复制到arg.list对象中,或者它们是通过引用传递的?

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

2 个答案:

答案 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的参数也会修改传入的变量。这不会发生。