2014-10-27 18 views
7

Tại saoSử dụng tên lập luận tương tự cho một chức năng được xác định trong chức năng khác

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

nguyên nhân lỗi? Nó có một cái gì đó để làm với a = một đối số, đặc biệt là với thực tế là các tên biến là như nhau. Chính xác thì điều gì đang xảy ra vậy?

Dưới đây là một số điểm giống nhau về mã mà làm việc như mong đợi:

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 

Trả lời

6

Vấn đề là, as explained in the R language definition:

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

Trong khối mã đầu tiên của bạn, khi bạn gọi g() mà không cần bất kỳ đối số, nó rơi trở về giá trị mặc định của nó a, đó là a. Đánh giá rằng trong "khung chức năng" (tức là môi trường được tạo bởi cuộc gọi đến g()), nó tìm thấy đối số có tên khớp với ký hiệu a và giá trị của nó là a. Khi tìm giá trị của số đó a, nó tìm đối số có tên khớp với biểu tượng đó và có giá trị là a. Khi ...

Như bạn thấy, bạn đang mắc kẹt trong một vòng lặp, đó là những gì được thông báo lỗi đang cố gắng để cho bạn biết:

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

nỗ lực thứ hai của bạn, trong đó kêu gọi g(a) hoạt động như bạn mong đợi, bởi vì bạn đã cung cấp một cuộc tranh cãi, và, 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.

có nó tìm thấy một biểu tượng a, được ràng buộc với bất kỳ giá trị nào bạn đã chuyển vào đối số chính thức của hàm ngoài a và tất cả đều tốt.

4

Vấn đề là phần a=a. Một đối số không thể là mặc định của nó. Đó là một tham chiếu vòng tròn.

ví dụ này có thể giúp làm sáng tỏ cách thức hoạt động:

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

Lưu ý rằng a không có mặc định 1; nó có mặc định 2. Nó trông đầu tiên trong chức năng chính nó cho mặc định. Theo cách tương tự, a=a sẽ gây ra a làm mặc định riêng của nó là hình tròn.

+1

và thông báo lỗi trong R 3.1.1 là 'Lỗi trong g(): lời hứa đã được đánh giá: tham chiếu mặc định đệ quy hoặc các vấn đề trước đó? ' – Roland

+0

Điều đó hữu ích hơn nhiều so với thông báo lỗi tôi thấy (Lỗi: 'a' bị thiếu). Tôi có phiên bản R 3.0.2 (2013-09-25) - "Ném dĩa nhựa" – Adrian

Các vấn đề liên quan