Scala的堆栈:()与{}

时间:2014-05-28 09:25:49

标签: scala scope

我正在编写一些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
}

谢谢, 马克

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网站来显示更多代码并征求进一步的反馈。