【问题标题】:why is the use of return a bad habit in scala为什么在scala中使用return是一个坏习惯
【发布时间】:2014-05-05 19:54:10
【问题描述】:

我正在通过 coursera 上的函数式编程课程做 scala。我注意到自动样式检查器告诉我使用“return”是一个坏习惯。这是为什么?对我来说,使用 return 似乎会使代码更具可读性,因为任何其他程序员都可以立即看到它以及函数返回的内容。

例如,为什么会这样;

def sum(xs: List[Int]): Int = {
    if( xs.length == 0){
      return 0
    }else{
      return xs.head + sum(xs.tail)
    }
}

被认为比这更糟;

def sum(xs: List[Int]): Int = {
    if( xs.length == 0){
      0
    }else{
      xs.head + sum(xs.tail)
    }
}

我习惯了 javascript,所以这可能是我对它感到不安的一个原因。尽管如此,任何人都可以清楚为什么添加 return 语句会使我的代码变得更糟吗?如果是这样,为什么语言中有 return 语句?

【问题讨论】:

  • 最简单的答案是你不应该使用return。和往常一样,我想指出,您的代码中没有一个花括号是必需的,如果是我的代码,它们将被省略。
  • @RandallSchulz 伟大的思想!我还建议使用模式匹配而不是if...else。 (见我的回答)

标签: scala code-cleanup


【解决方案1】:

在 Java、Javascript 和其他命令式语言中,if...else 是一个流控制语句。

这意味着你可以这样做

public int doStuff(final boolean flag) {
    if(flag)
        return 1;
    else
        return 5;
}

但你不能这样做

public int doStuff(final boolean flag) {
    return if(flag)
        1;
    else
        5;
}

因为if...else 是一个语句,而不是一个表达式。为此,您需要使用三元运算符(严格地说是“条件运算符”),例如:

public int doStuff(final boolean flag) {
    return flag ? 1 : 5;
}

在 Scala 中,这是不同的。 if...else 构造是一个表达式,因此更类似于您习惯的语言中的条件运算符。所以,实际上你的代码最好写成:

def sum(xs: List[Int]): Int = {
    return if(xs.length == 0) {
      0
    } else {
      xs.head + sum(xs.tail)
    }
}

此外,函数中的最后一个表达式会自动返回,因此return 是多余的。事实上,由于代码只有一个表达式,大括号也是多余的:

def sum(xs: List[Int]): Int = 
    if(xs.length == 0) 0
    else xs.head + sum(xs.tail)

所以,回答你的问题:不鼓励这样做,因为如果 Scala 中的 if...else 构造是对性质的误解。

但这只是一点点,你真的应该使用pattern matching

def sum(xs: List[Int]): Int = xs match {
   case Nil => 0
   case head::tail => head + sum(tail)
}

这是更惯用的 Scala。了解如何使用(和滥用)模式匹配,您将为自己节省大量行代码。

【讨论】:

  • +1 用于模式匹配,指针有效,非常感谢。
【解决方案2】:

我认为这个问题的另一个答案

为什么在scala中使用return是一个坏习惯

是在闭包中使用时 return 将从方法而不是闭包本身返回。

例如,考虑以下代码:

def sumElements(xs: List[Int]): Int = { 
  val ys: List[Int] = xs.map { x => 
    return x + 1
  }
  return ys.sum 
}

很容易忽略,当使用sumElements(List(1, 2, 3, 4)) 调用此代码时,结果将是2 而不是10。这是因为map 中的return 将从sumElements 返回,而不是从map 调用返回。

【讨论】:

    【解决方案3】:

    在 Scala 中,每一行都是expression,而不是statement。语句通常没有返回值,但表达式有。

    块的最后一个结果将是返回值,因此样式指南基于此假设进行操作。返回将是块的异常退出。

    def sum(xs: List[Int]): Int = { if(xs.isEmpty) return 0 xs.head + sum(xs.tail) }

    那里的 return 语句会导致函数在返回时退出,并且通常会导致代码比使用 if/else 逻辑编写的代码更难理解,就像你之前所做的那样。我相信风格决定背后的理性是不鼓励这种类型的编程,因为它会使程序更难理解。

    【讨论】:

      猜你喜欢
      • 2018-05-18
      • 2020-01-03
      • 1970-01-01
      相关资源
      最近更新 更多