在下面的代码中,我看到警告no tail calls found
,但是当写为扩展函数时,同一函数没有该警告。现在我很困惑我的IDE是错的,还是我的扩展方法实际上不是尾部递归的,还是编译器处理实例方法与扩展函数之间的区别?
作为第二个警告
递归调用不是尾部调用]
表明此调用是递归的,但不是尾调用。
这是因为正在使用不同的实例作为目标(next
而不是this
)来调用该函数,所以tailrec
在这种情况下实际上没有效果。如果将目标替换为this
,则编译器将停止发出任何警告。
我假设扩展功能在编译时没有任何警告,因为它们被编译为静态(即非实例)功能,这意味着转换后的代码看起来(大致)类似于
@Nullable
public static final SLLNode2 getNodeForValue2(@NotNull SLLNode2 $this$getNodeForValue2, int valToFind) {
Intrinsics.checkParameterIsNotNull($this$getNodeForValue2, "$this$getNodeForValue2");
if ($this$getNodeForValue2.getValue() == valToFind) {
return $this$getNodeForValue2;
} else {
SLLNode2 var10000 = $this$getNodeForValue2.getNext();
return var10000 != null ? getNodeForValue2(var10000, valToFind) : null;
}
}
很明显包含一个递归的尾部调用。
但是,我不确定这种区别是有意为之的,因为扩展功能的编译方式应该是实现细节,并且实例功能示例应该]((?)是等效优化的。