存储传递风格

存储传递风格是一种技术，用来建模可变而不用使用全局变量。它通常出现在将指令式程序转换成纯函数式程序的场合。

实例
考虑如下这个用“非存储传递风格”书写的JavaScript程序：

var lastWasA = false

// treebin表示字符串的二叉树。
// treebin要么是一个字符串，
// 要么是{l : <treebin>, r: <treebin>}。

// 对这个树的叶子的中序遍历含有'a'跟随着'b'吗？
function aThenB(treebin) {
  if (typeof(treebin) === "string") {
    if (treebin === "a") {
      lastWasA = true;
      return false;
    } else if (treebin === "b") {
      if (lastWasA) {
        return true;
      } else {
        lastWasA = false;
        return false;
      }
    } else {
      lastWasA = false;
      return false;
    }
  } else { // 不是字符串，必定是内部节点：
    return ((aThenB(treebin.l))||(aThenB(treebin.r)));
  }
}

这里包含了对全局变量lastWasA引用。在存储传递风格中，一个或更多的全局变量在每次函数调用时一起传入，而且从每次调用返回并传入下次函数调用从而形成牵连（thread）。代码可以写为如下:

function aThenB(treebin, lastWasA) {
  if (typeof(treebin) === "string") {
    if (treebin === "a") {
      return {result: false, lastWasA: true};
    } else if (treebin === "b") {
      if (lastWasA) {
        return {result: true, lastWasA: false};
      }
    } else {
      return {result: false, lastWasA: false};
    }
  } else { // 不是字符串，必定是内部节点：
    var leftCall = aThenB(treebin.l, lastWasA);
    if (leftCall.result) {
      return {result: true, lastWasA: false}
    } else {
      return aThenB(treebin.r, leftCall.lastWasA);
    }
  }
}

注意现在每次调用都接受一个额外的实际参数lastWasA，还返回两个值：平常的返回值，和一个新值来表示原先的可变变量lastWasA的状态。

写存储传递风格的程序可能非常痛苦，但通过将状态隔离在函数调用之中，有助于消除竞争条件，从使代码潜在的更加可并行化。

参见


引用

Category:软件设计模式
Category:函数式编程