为什么 "Sum()" 在递归 R 函数中“+”失败的地方成功?
Why does "Sum()" succeed where "+" fails in recursive R function?
我正在试验 R 中的函数式编程范例。我定义了一个函数,它对从 n 到 m[=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
条件。但是行为没有明确定义,你不应该依赖它。
如果没有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)
我正在试验 R 中的函数式编程范例。我定义了一个函数,它对从 n 到 m[=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
条件。但是行为没有明确定义,你不应该依赖它。
如果没有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)