2015-08-16 2 views
12

Если мы рассмотрим тело функции с точками ... в списке аргументов, мы обычно можем найти функцию, которая получает эти аргументы точек.Где обрабатываются отсутствующие точки (`...`)?

Например, мы можем видеть в теле sapply(), что аргументы точек передаются до lapply().

sapply 
# function (X, FUN, ..., simplify = TRUE, USE.NAMES = TRUE) 
# { 
#  FUN <- match.fun(FUN) 
#  answer <- lapply(X = X, FUN = FUN, ...) 
#  ## rest of function body 
# } 
# <bytecode: 0x000000000e05f0b0> 
# environment: namespace:base> 

Однако в lapply(), есть точки ... в списке аргументов, но не в теле функции.

lapply 
# function (X, FUN, ...) 
# { 
#  FUN <- match.fun(FUN) 
#  if (!is.vector(X) || is.object(X)) 
#   X <- as.list(X) 
#  .Internal(lapply(X, FUN)) 
# } 
# <bytecode: 0x0000000009414f08> 
# <environment: namespace:base> 

Итак, где многоточие ... аргументы в lapply() обрабатываются? Что/куда они перешли? Мы не можем передать их match.fun(). Я предполагаю, что они переданы в .Internal(), но я не вижу причин для этого, когда я не вижу, чтобы они передавались в любую функцию в теле функции.

ответ

13

Они явно не прошли в .Internal, но я считаю, что они доступны для do_lapply (в SRC/основной/apply.c) с помощью динамической области. Правила обзора могут несколько отличаться от обычных, поскольку .Internal является примитивной функцией.

Вы можете видеть, что ... (R_DotsSymbol) добавляется к вызову функции lapply создает, таким образом, они доступны для вызова функции для каждого элемента списка. tmp приблизительно эквивалентен X[[i]] и R_fcall приблизительно эквивалентен FUN(X[[i]], ...).

SEXP tmp = PROTECT(LCONS(R_Bracket2Symbol, 
     LCONS(X, LCONS(isym, R_NilValue)))); 
SEXP R_fcall = PROTECT(LCONS(FUN, 
      LCONS(tmp, LCONS(R_DotsSymbol, R_NilValue)))); 
Смежные вопросы