遞迴函數若需返回值,每一層遞迴呼叫都必須以 return 傳遞。遺漏任何一層 return 都會導致最終返回 null。
<?php
// 錯誤:遞迴呼叫未 return
function testWrong($i) {
$i -= 4;
if ($i < 3) {
return $i;
} else {
testWrong($i); // 缺少 return
}
}
// 正確:每層都 return
function testCorrect($i) {
$i -= 4;
if ($i < 3) {
return $i;
} else {
return testCorrect($i); // 關鍵 return
}
}
var_dump(testWrong(30)); // NULL
var_dump(testCorrect(30)); // int(-2)
return 或執行到結尾,隱性返回 null。return $value,值返回給直接呼叫者。return,它收到值後不做任何事,函數結束返回 null。null。「遞迴呼叫前面一定要加 return,除非你真的不需要返回值。」
<?php
// 二元樹尋找節點,找到返回節點,未找到返回 null
function findNode($node, $targetId) {
if (!$node) return null;
if ($node->id === $targetId) return $node;
// 左子樹找到直接返回,否則找右子樹
$left = findNode($node->left, $targetId);
if ($left) return $left;
return findNode($node->right, $targetId); // 這裡的 return 不可少
}
<?php
function debugRecursive($param, $depth = 0) {
$indent = str_repeat(' ', $depth);
error_log("{$indent}→ CALL: " . json_encode($param));
if (isBase($param)) {
$result = compute($param);
error_log("{$indent}← RETURN: " . json_encode($result));
return $result;
}
$next = transform($param);
$result = debugRecursive($next, $depth + 1);
error_log("{$indent}← RETURN: " . json_encode($result));
return $result;
}
掌握此原則,遞迴函數返回值問題將不再困擾。