2014-10-27 102 views
7

爲什麼使用其他函數中定義的函數相同的參數名稱

f <- function(a) { 
    g <- function(a=a) { 
     return(a + 2) 
    } 
    return(g()) 
} 
f(3) # Error in a + 2: 'a' is missing 

原因的錯誤?它與a =一個參數有關,特別是與變量名稱相同的事實。究竟發生了什麼?

這裏有一些相似的代碼塊按預期工作:

f <- function(a) { 
    g <- function(a) { 
     return(a + 2) 
    } 
    return(g(a)) 
} 
f(3) # 5 

f <- function(a) { 
    g <- function(g_a=a) { 
     return(g_a + 2) 
    } 
    return(g()) 
} 
f(3) # 5 

g <- function(a) a + 2 
f <- function(a) g(a) 
f(3) # 5 

回答

6

的問題是,as explained in the R language definition

The default arguments to a function are evaluated in the evaluation frame of the function.

在你的第一個代碼塊,當你調用g()不帶任何參數,它倒在的a它的默認值,這是a。在「函數的框架」(即通過調用g()創建的環境)中評估該函數,它找到名稱與符號a匹配的參數,其值爲a。當它查找a的值時,它會找到名稱與該符號相匹配的參數,其值爲a。當...

正如你所看到的,你死循環,這是錯誤消息要告訴你:

Error in g() : 
    promise already under evaluation: recursive default argument reference or 
earlier problems? 

你的第二次嘗試,它調用g(a)如你預期的,因爲你供應已經參數的工作原理,以及as explained in the same section of R-lang

The supplied arguments to a function are evaluated in the evaluation frame of the calling function.

有它找到一個符號a,它綁定到你傳遞給外函數的正式參數a的任何值,一切都很好。

4

的問題是a=a一部分。參數不能是它自己的默認值。這是一個循環參考。

這個例子可以幫助闡明它是如何工作的:

x <- 1 
f <- function(a = x) { x <- 2; a } 
f() 
## [1] 2 

注意a沒有默認的1;它具有默認值2.它首先在函數本身中默認使用。以類似的方式a=a將導致a成爲它自己的循環默認值。

+1

和R 3.1.1中的錯誤信息是'g中的錯誤(): 諾言已經在評估中:遞歸默認參數引用或更早的問題? ' – Roland 2014-10-27 17:01:52

+0

這比我看到的錯誤消息更有幫助(錯誤:缺少'a')。我有R版本3.0.2(2013-09-25) - 「飛盤帆船」 – Adrian 2014-10-27 17:29:23

相關問題