我正在编写一些scala代码:
def getOpponentOf(request)
= if (getPlayerTupleOf(request)._1.id == request.id)
getPlayerTupleOf(request)._1
else getPlayerTupleOf(request)._2
现在,我的命令性思维开始了:“嘿,为什么我不会定义一个引用getPlayerTuple的局部变量,然后使用该引用。
但是我必须使用{}范围而不是()(更实用?) 假设函数getPlayerTupleOf也是完美的功能,即使用()范围,无副作用等。
例如,执行上述操作时,性能/编译器的含义是什么:
def getOpponentOf(request) = {
val playerTuple = getPlayerTupleOf(request)
if (playerTuple._1.id == request.id)
playerTuple._1
else playerTuple._2
}
谢谢, 马克
答案 0 :(得分:5)
使用块{}不反对函数式编程。 Scala“val”声明等同于其他函数语言中存在的“let”绑定(例如ML,F#),因此它们是完全“功能”的概念。不起作用的是使用真实的变量定义为 var 而不是 val 。
关于性能:编译器通常无法确定您的方法是无副作用的,并且可以“缓存”具有相同参数的多个调用(例如,以本地“变量”的形式)。因此,编译后的代码会在编写代码时有效地调用该方法。 JIT仍然可以选择在运行时有效地优化它,它可能会也可能不会发生,具体取决于您的方法的实现方式和其他因素。
我认为还有其他方面需要考虑:简洁性,可维护性,第二个版本在这里获胜:没有代码重复,变量的名称可以帮助理解代码。
答案 1 :(得分:1)
您是否考虑过这种方法?
def getOpponentOf(request) = getPlayerTupleOf(request) match {
case (opponent, _) if opponent.id == request.id => opponent
case (_, opponent) => opponent
}
我真的不知道你的元组中的项目代表什么,这就是为什么你应该尽量避免使用元组,除非它们的含义本质上是清晰的。也许某种类型的命名类型在这里会更好用(再次尝试猜测你的元组意味着什么):
case class Players(playerA: Player, playerB: Player)
def getOpponentOf(request) = getPlayersOf(request) match {
case Players(a, _) if a.id = request.id => a
case Players(_, b) => b
}
如果您在很多其他地方使用getPlayersOf
的结果,这可能会有意义。如果没有,那么可能更简单的事情是将getOpponent
(或简称opponent
)放在您的请求对象上,然后所有这些都变为:
request.opponent
您可以考虑使用Stack Exchange的Code Review网站来显示更多代码并征求进一步的反馈。