Scala:绑定时间
Scala: binding time
在策略模式中,实现如下:
object StrategyPattern {
def add(a: Int, b: Int) = a + b
def subtract(a: Int, b: Int) = a - b
def multiply(a: Int, b: Int) = a * b
def execute(callback:(Int, Int) => Int, x: Int, y: Int) = callback(x, y)
def main(args: Array[String]) {
println("Add: " + execute(add, 3, 4))
println("Subtract: " + execute(subtract, 3, 4))
println("Multiply: " + execute(multiply, 3, 4))
}
}
我想知道(如果对绑定时间的 types/forms 有很好的参考,我想知道如何理解其他情况)如果方法 add, substract, and multiply
的绑定时间是"construction time"
(如果我可以这么说的话),或在 runtime
?
简单的答案是(对于具体的 classes)方法定义在编译时绑定到方法名称,就像它们在 Java 中一样。例如,您的 add
方法完全等同于此 Java 定义:
public int add(int a, int b) {
return a + b;
}
非最终方法
如果您从调用站点的角度分析非最终方法的绑定时间,其中具体 class 静态未知,则方法名称将被视为具有运行时绑定到它的实现(由于 subclassing/overriding)。
动态类加载
简单的答案接近事实,但 JVM 中的动态 class 加载使事情变得有点复杂。由于动态 class 加载,方法定义在技术上在运行时绑定到完全限定名称(例如,my.pkg.StrategyPattern.add
)。当然可以有一个 my.package.StrategyPattern
模块的替代实现,并在其中动态选择(通过加载相应的 class 文件)。
当然,这种区别只与包含StrategyPattern
定义的编译单元之外的代码有关。在编译单元内,方法总是在编译时被认为是绑定的。
策略
既然你问的是策略模式,我猜你还有别的想法?如果你问你是否可以在运行时 "strategies" 中 select,你可以:
val op: (Int, Int) => Int =
if (args(0) == "+") add
else if (args(0) == "-") subtract
else multiply
execute(op, 3, 4)
在这种情况下,op
在运行时绑定到一个 "strategy" 函数,但 add
、subtract
和 multiply
仍然绑定到它们在编译时的定义。
这些方法中的每一个在编译时也与匿名 Function2
class 相关联,并且适当的 class 在运行时根据条件表达式的结果。这个细节实际上与绑定时间分析无关,因为 add
、subtract
和 multiply
标识符的含义在编译时是固定的。
在策略模式中,实现如下:
object StrategyPattern {
def add(a: Int, b: Int) = a + b
def subtract(a: Int, b: Int) = a - b
def multiply(a: Int, b: Int) = a * b
def execute(callback:(Int, Int) => Int, x: Int, y: Int) = callback(x, y)
def main(args: Array[String]) {
println("Add: " + execute(add, 3, 4))
println("Subtract: " + execute(subtract, 3, 4))
println("Multiply: " + execute(multiply, 3, 4))
}
}
我想知道(如果对绑定时间的 types/forms 有很好的参考,我想知道如何理解其他情况)如果方法 add, substract, and multiply
的绑定时间是"construction time"
(如果我可以这么说的话),或在 runtime
?
简单的答案是(对于具体的 classes)方法定义在编译时绑定到方法名称,就像它们在 Java 中一样。例如,您的 add
方法完全等同于此 Java 定义:
public int add(int a, int b) {
return a + b;
}
非最终方法
如果您从调用站点的角度分析非最终方法的绑定时间,其中具体 class 静态未知,则方法名称将被视为具有运行时绑定到它的实现(由于 subclassing/overriding)。
动态类加载
简单的答案接近事实,但 JVM 中的动态 class 加载使事情变得有点复杂。由于动态 class 加载,方法定义在技术上在运行时绑定到完全限定名称(例如,my.pkg.StrategyPattern.add
)。当然可以有一个 my.package.StrategyPattern
模块的替代实现,并在其中动态选择(通过加载相应的 class 文件)。
当然,这种区别只与包含StrategyPattern
定义的编译单元之外的代码有关。在编译单元内,方法总是在编译时被认为是绑定的。
策略
既然你问的是策略模式,我猜你还有别的想法?如果你问你是否可以在运行时 "strategies" 中 select,你可以:
val op: (Int, Int) => Int =
if (args(0) == "+") add
else if (args(0) == "-") subtract
else multiply
execute(op, 3, 4)
在这种情况下,op
在运行时绑定到一个 "strategy" 函数,但 add
、subtract
和 multiply
仍然绑定到它们在编译时的定义。
这些方法中的每一个在编译时也与匿名 Function2
class 相关联,并且适当的 class 在运行时根据条件表达式的结果。这个细节实际上与绑定时间分析无关,因为 add
、subtract
和 multiply
标识符的含义在编译时是固定的。