这是一种可以应用于任何语言的模式,前提是该语言是在允许重新分配与代码块关联的名称的环境中编写的。
在计算机中,代码和数据存在于内存中。在编程语言中,我们使用名称来指代那些内存“块”。
int a = 0;
将“命名”一些内存字节数“a”。它还将“分配”该内存对应于 0 的字节值。根据类型系统,
int add(int first, int second) {
return first + second;
}
将“命名”一些内存字节数“添加”。它还将“分配”该内存以包含机器指令,以在调用堆栈中查找两个“int”数字,将它们相加,并将结果放在调用堆栈上的适当位置。
在将名称分隔(并维护)代码块的类型系统中,最终结果是您可以轻松地通过引用传递代码块,就像您可以通过引用改变内存一样。关键是要确保类型系统只“匹配”兼容的类型,否则传递代码块可能会导致错误(比如在最初定义为返回 int 时返回 long)。
在 Java 中,所有类型都解析为“签名”,它是方法名称和“类型”的字符串表示形式。查看提供的添加示例,签名是
// This has a signature of "add(I,I)I"
int add(int first, int second) {
return first + second;
}
如果 Java 支持(如 Clojure 那样)方法名分配,它必须扩展其声明的类型系统规则,并允许方法名分配。一个假的方法分配示例在逻辑上看起来像
subtract = add;
但这需要使用强类型(以匹配 Java)“类型”声明减法。
public subtract(I,I)I;
如果不小心,这样的声明很容易踩到语言中已经定义的部分。
但要回到您的答案,在支持此类的语言中,名称基本上是指向代码块的指针,并且可以重新分配,前提是您不破坏输入和返回参数的期望。