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

Basics of argument passing in R's functions

R 如何解释行: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)
  }
}

变量通过引用嵌入到列表中(至少如果您使用向量)。

证明:

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"

如果您更改一项,将创建一个副本 ("copy on modification"):

> x[1]=42
> address(x)
[1] "0x417a470"
> al.x <- arg.list[[1]]
> address(al.x)
[1] "0x37598c0"

编辑:

正如@HongOoi 所说:R 在语义上从不使用引用(环境中的对象除外 class),而是使用变量的副本。它 "is clever enough to avoid copies until they are really required" ("copy on [first] modification")。函数参数按语义传递 "by value"(即使在发生修改之前使用引用)。

R 的语义 是函数参数总是按值 传递。底层实现不一定要为参数制作新的副本,以节省内存。但是您的函数将表现得好像它有 brand-new 个副本可以使用。

这意味着您不必担心在函数外部更改变量,因为您在函数内部更改了它:

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 是 pass-by-reference,那么修改 f 的参数也会修改传入的变量。这不会发生。