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

Why does "Sum()" succeed where "+" fails in recursive R function?

我正在试验 R 中的函数式编程范例。我定义了一个函数,它对从 nm[=25= 的整数序列求和].当我使用 sum() 函数时 returns 预期结果:

sumRange <- function(n, m) {
    if (n <= m) { 
        return(sum(n, sumRange((n + 1), m)))
    }
}

sumRange(1, 10)
# [1] 55

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

sumRange <- function(n, m) {
    if (n <= m) {
        return(n + sumRange((n + 1), m))
    }
}

sumRange(1, 10)
# numeric(0)

为什么运算符+在这个递归函数中不起作用?有没有一种方法可以重写该函数以实现它?

问题是您从未指定 else 条件,因此在递归结束时,当 if 条件失败时,R 似乎返回 NULL。返回 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

如果没有return(使用显式或隐式return语句)被执行,那么R函数似乎return一个NULL对象。

如果将数值添加到 this 对象,它将简单地 return numeric(0)

因此,第二种情况发生的情况是,当 n 达到 11 时,它 return 是一个 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)