[R如何解釋論點:arg.list <- list(x, y)
在功能下面的定義,它複製x
和y
到arg.list
對象時執行發生,或者它們是通過引用傳遞?基礎路過R中的功能
fplot <- function(x, y, add=FALSE){
arg.list <- list(x, y)
if(!add){
plot(arg.list))
}else{
lines(arg.list)
}
}
[R如何解釋論點:arg.list <- list(x, y)
在功能下面的定義,它複製x
和y
到arg.list
對象時執行發生,或者它們是通過引用傳遞?基礎路過R中的功能
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"
如果更改一個項目副本將被創建(「關於修改本」) :
> x[1]=42
> address(x)
[1] "0x417a470"
> al.x <- arg.list[[1]]
> address(al.x)
[1] "0x37598c0"
編輯:
作爲@HongOoi說:R語義上從不使用引用(環境類中的對象除外),但複製變量。它「足夠聰明,以避免複製,直到他們真正需要」(「複製[第一]修改」)。函數參數在語義上「按值」傳遞(即使引用被使用直到修改發生)。
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
的說法也將修改傳入的變量。這不會發生。
那麼R尤達的答案呢? – Qbik
尤達的答案是關於R的內部。它足夠聰明,除非需要,否則不要複製一個參數。例如,如果我的函數'f'完全不修改它的參數:'f < - function(z){return(z + 1)}'那麼它就不會再爲'z'創建一個新副本。然而,如果參數的新副本被創建,'f'的外部行爲總是_as。 –
有一些地區,R是通過參考,即環境。我可能會在後面添加這個答案。 –
請注意,您當前的問題與傳遞給函數的參數無關(如標題所示),而是從標量向量變量構造容器變量......這真的是您的意圖嗎? –
@R尤達,在我的實際函數中,'x'和'y'是'data.frame',然後我使用它們:'x $ var1' – Qbik
如果在外部或內部修改x和y,該功能(直到此時「第一次修改時複製」仍爲真,以避免不必要的存儲器複製)。 'x $ var'產生一個向量...... –