[英]Mimicking Pass-By-Reference in Python/Javascript Using Wrappers - Good Practice?
假設我要在函數內部修改數字或其他原始類型。 例如,如下所示(注意:偽代碼):
// apply fn to every value in a tree, in-order traversal
function treeReduce (tree, fn, result):
if (tree == undefined) return
treeReduce(tree.left, fn, result)
result = fn(result, tree.value)
treeReduce(tree.right, fn, result)
sum = 0
treeReduce(myTree, +, sum)
顯然,這是行不通的,因為只是重新分配了result
,並且傳入的sum
將看不到修改。 因此,我解決此問題的通用方法(在任何傳遞值的語言(如Python或Javascript)中都使用包裝器:
// apply fn to every value in a tree, in-order traversal
function treeReduce (tree, fn, result):
if (tree == undefined) return
treeReduce(tree.left, fn, result)
result[0] = fn(result[0], tree.value)
treeReduce(tree.right, fn, result)
sumWrapper = [0]
treeReduce(myTree, +, sumWrapper)
但是,我最近在互聯網上搜索了這是否是一種常見模式,並且找不到太多有關此模式的信息。 具體來說,我想知道三件事:
可以這樣做,但是會增加函數的“副作用” ,大多數編碼人員建議盡量減少這些副作用 。 相反,您可以為其使用函數的返回值。 然后,您的代碼仍將傳遞“ previous”(或“ start”)值作為原語,但返回結果。
這是在JS中的外觀(我花了一些不小的瑣碎的fn
來演示它執行了有序執行):
// apply fn to every value in a tree, in-order traversal function treeReduce (tree, fn, start) { if (tree === undefined) return start let result = treeReduce(tree.left, fn, start) result = fn(result, tree.value) result = treeReduce(tree.right, fn, result) return result } let myTree = { value: 1, left: { value: 2 }, right: { value: 3 } } let result = treeReduce(myTree, (a,b) => a*a+b, 0) console.log(result)
請注意,以上內容現在可以更簡潔地編寫:
// apply fn to every value in a tree, in-order traversal function treeReduce (tree, fn, start) { return !tree ? start : treeReduce(tree.right, fn, fn(treeReduce(tree.left, fn, start), tree.value)) } let myTree = { value: 1, left: { value: 2 }, right: { value: 3 } } let result = treeReduce(myTree, (a,b) => a*a+b, 0) console.log(result)
在Python中:
import collections
Tree = collections.namedtuple('Tree', ['value', 'left', 'right'])
# apply fn to every value in a tree, in-order traversal
def treeReduce (tree, fn, start):
return start if not tree else (
treeReduce(tree.right, fn, fn(treeReduce(tree.left, fn, start), tree.value))
)
myTree = Tree(1, Tree(2,None,None), Tree(3,None,None))
result = treeReduce(myTree, lambda a,b: a*a+b, 0)
print(result)
JS和Python都允許將其擴展到需要設置多個原始值的情況:函數可以返回數組/列表/元組/對象,然后可以通過將它們解壓縮/分解為單獨的變量來進行賦值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.