在 R 的函数中传递参数的基础知识
Basics of argument passing in R's functions
R 如何解释行: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)
}
}
变量通过引用嵌入到列表中(至少如果您使用向量)。
证明:
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
的参数也会修改传入的变量。这不会发生。
R 如何解释行: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)
}
}
变量通过引用嵌入到列表中(至少如果您使用向量)。
证明:
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
的参数也会修改传入的变量。这不会发生。