为什么" Sum()"成功的地方" +"递归R函数失败?

时间:2017-10-22 08:19:33

标签: r function recursion operator-keyword declarative

我正在试验R中的声明性编程范例。我已经定义了一个函数,它将从 n m 的整数序列求和。当我使用sum()时,该函数返回预期的结果:

> sumRange <- function(n, m) if (n <= m) return(sum(n, sumRange((n+1), m)))
> sumRange(1, 10)
[1] 55

但是,当我使用+运算符时,函数返回numeric(0)

> sumRange <- function(n, m) if (n <= m) return(n + sumRange((n+1), m))
> sumRange(1, 10)
numeric(0)

为什么运算符+在这个递归函数中不起作用?有没有办法重写函数,以便它呢?

2 个答案:

答案 0 :(得分:1)

问题是你从不指定else条件,因此在递归结束时,当NULL条件失败时,R似乎返回if。返回0作为else条件可以解决您的问题:

sumRange <- function(n, m) return(ifelse (n <= m, (n +  sumRange((n+1), m)), 0))
sumRange(1, 10)
[1] 55

请注意,这主要是为递归定义基本情况。一个基本案例,当命中时,结束递归并导致堆栈上的调用被解开。

要查看代码编写方式的问题,请尝试明确写出您的函数:

sumRange <- function(n, m) {
    if (n <= m) {
        return(n + sumRange((n+1), m))
    }
    // but what gets returned if n > m ?
    // this is undefined behavior
}

我不是R大师,但我的理解是R是用C语言编写的,而C可能允许这样的递归而没有else条件。但是行为没有明确定义,你不应该依赖它。

Demo

答案 1 :(得分:1)

如果没有返回(使用显式或隐式返回语句),则R函数似乎返回NULL对象。

如果您向此对象添加数值,它将只返回numeric(0)

所以,在第二种情况下发生的情况是,当n达到11时,它返回一个NULL对象,并返回向其添加值。但是NULL + 10 + 9 .. = numeric(0)

使用

进行检查
no_ret <- function ()
{
 # just return nothing
}

obj <- no_ret()
obj
# NULL 
class(obj)
# "NULL
new_obj <- obj + 10
new_obj
# numeric(0)

执行第一个函数时,sum语句得到的是 其中包含NULL的向量。例如, vec <- c(NULL, 10, 9,...)实际上是vec <- c(10, 9, ...),因此您可以获得预期的结果。

> c(NULL, 10:1)
 [1] 10  9  8  7  6  5  4  3  2  1
> sum(NULL, 10:1)
[1] 55

> NULL + 10:1
integer(0)