can*_*his 1 scala code-cleanup
我正在通过课程中的函数式编程课程进行scala.我注意到自动样式检查器告诉我使用'return'是一个坏习惯.这是为什么?对我而言,似乎使用return会使代码更具可读性,因为任何其他程序员都可以立即看到它以及函数返回的内容.
例如,这是为什么;
def sum(xs: List[Int]): Int = {
if( xs.length == 0){
return 0
}else{
return xs.head + sum(xs.tail)
}
}
Run Code Online (Sandbox Code Playgroud)
被认为比这更糟糕;
def sum(xs: List[Int]): Int = {
if( xs.length == 0){
0
}else{
xs.head + sum(xs.tail)
}
}
Run Code Online (Sandbox Code Playgroud)
我习惯了javascript,所以这可能是我对此感到不安的原因.不过,任何人都可以明白为什么添加return语句会让我的代码变得更糟吗?如果是这样,为什么语言中有返回声明?
在Java中,Javascript和其他命令式语言if...else是一种流控制语句.
这意味着你可以这样做
public int doStuff(final boolean flag) {
if(flag)
return 1;
else
return 5;
}
Run Code Online (Sandbox Code Playgroud)
但你不能这样做
public int doStuff(final boolean flag) {
return if(flag)
1;
else
5;
}
Run Code Online (Sandbox Code Playgroud)
因为if...else是陈述而不是表达.要实现这一点,您需要使用三元运算符(严格来说是"条件运算符"),例如:
public int doStuff(final boolean flag) {
return flag ? 1 : 5;
}
Run Code Online (Sandbox Code Playgroud)
在Scala中,这是不同的.该if...else结构是一个表达式,所以更接近您所使用的语言条件运算符.所以,事实上你的代码写得更好:
def sum(xs: List[Int]): Int = {
return if(xs.length == 0) {
0
} else {
xs.head + sum(xs.tail)
}
}
Run Code Online (Sandbox Code Playgroud)
此外,函数中的最后一个表达式会自动返回,因此return是多余的.事实上,由于代码只有单个表达式,大括号也是多余的:
def sum(xs: List[Int]): Int =
if(xs.length == 0) 0
else xs.head + sum(xs.tail)
Run Code Online (Sandbox Code Playgroud)
所以,回答你的问题:这是不鼓励的,因为如果if...elseScala中的结构是对性质的误解.
但除此之外,这一点都有点,你应该真正使用模式匹配
def sum(xs: List[Int]): Int = xs match {
case Nil => 0
case head::tail => head + sum(tail)
}
Run Code Online (Sandbox Code Playgroud)
这是更惯用的Scala.了解如何使用(和滥用)模式匹配,您将节省大量的代码行.
我想为什么问题的另一个答案
为什么在scala中使用返回一个坏习惯
是否在闭包中使用时返回将从方法返回而不是从闭包本身返回.
例如,考虑以下代码:
def sumElements(xs: List[Int]): Int = {
val ys: List[Int] = xs.map { x =>
return x + 1
}
return ys.sum
}
Run Code Online (Sandbox Code Playgroud)
很容易错过,当调用此代码时sumElements(List(1, 2, 3, 4)),结果将是2和不是10.这是因为return内部map将从呼叫返回sumElements而不是从map呼叫返回.