1

[R如何解釋論點:arg.list <- list(x, y)在功能下面的定義,它複製xyarg.list對象時執行發生,或者它們是通過引用傳遞?基礎路過R中的功能

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

請注意,您當前的問題與傳遞給函數的參數無關(如標題所示),而是從標量向量變量構造容器變量......這真的是您的意圖嗎? –

+0

@R尤達,在我的實際函數中,'x'和'y'是'data.frame',然後我使用它們:'x $ var1' – Qbik

+0

如果在外部或內部修改x和y,該功能(直到此時「第一次修改時複製」仍爲真,以避免不必要的存儲器複製)。 'x $ var'產生一個向量...... –

回答

3

變量通過引用嵌入到列表中(至少在使用向量時)。

證明:

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語義上從不使用引用(環境類中的對象除外),但複製變量。它「足夠聰明,以避免複製,直到他們真正需要」(「複製[第一]修改」)。函數參數在語義上「按值」傳遞(即使引用被使用直到修改發生)。

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的說法也將修改傳入的變量。這不會發生。

+0

那麼R尤達的答案呢? – Qbik

+0

尤達的答案是關於R的內部。它足夠聰明,除非需要,否則不要複製一個參數。例如,如果我的函數'f'完全不修改它的參數:'f < - function(z){return(z + 1)}'那麼它就不會再爲'z'創建一個新副本。然而,如果參數的新副本被創建,'f'的外部行爲總是_as。 –

+0

有一些地區,R是通過參考,即環境。我可能會在後面添加這個答案。 –