scala中为什么不建议用return

来源:互联网 发布:基于qt的socket编程 编辑:程序博客网 时间:2024/04/28 16:02

scala中为什么不建议用return


在scala中使用return的话,编译的时候会提示the latest statement is method is automatically returned, use of th return keyword is redundant.这个警告是说最后一个语句的结果会自动返回,不需要使用return语句。
scala不建议使用return关键字,这一点在刚刚接触函数式编程的时候感觉非常难受。有return会让代码结果更清晰不是么?在查阅之后,整理了以下几点不建议使用return关键字的原因。

1.要写函数而不是指令

函数式编程的一个重要理念就是要尽量使代码由无状态的函数构成,而不是给计算机发出指令。例如

f(x) = x + 1    //式1.1

是一个函数。
scala会自动将最后一个表达式的结果作为返回结果

def f(x:Int) = x + 1    //式1.2def f(x:Int):Int = return x + 1     //式1.3

从以上两种分别使用和不使用return的表达方式来看,不使用return看起来更接近函数,而使用了return则更像指令。

2.return影响类型推断

scala中的类型推断机制会自动将最后一个表达式的类型作为返回类型,例如式1.2中,函数能够自动识别结果为Int类型。如果使用了return语句,就会破坏类型推断机制,需要显式注明返回类型,例如式1.3。

3.使用return返回含义模糊

有时使用了return会让代码的返回更加混乱,这个歧义主要产生于return到底返回到哪一层函数。

def add(n:Int, m:Int): Int = return n + m     //式3.1def sum1(ns: Int*): Int = ns.foldLeft(0)(add)    //式3.2

例如上述代码,目前来看还没有什么问题,但是如果写成下面的形式

def sum2(ns: Int*): Int = ns.foldLeft(0)((n,m) => return n+m)    //式3.3

直观感受式3.3与3.1+3.2应该是等效的。但事实上sum1(1,2,3) = 6,而sum2(1,2,3) = 1.
原因就是return语句会直接让它所出现的函数返回。也就会直接break foldLeft的循环返回结果。
再看另外一个例子:

def foo: Int = {     val sumR: List[Int] => Int = _.foldLeft(0)((n, m) => return n + m)    sumR(List(1,2,3)) + sumR(List(4,5,6))}

首先定义一个匿名函数,在调用匿名函数的时候,相当于return语句出现在了foo函数中。因此foo() = 1

4.NonLocalReturnControl

在scala的循环中的return实际上是通过抛异常实现的,编译后发现

return value

被编译成了

throw new NonLocalReturnControl(key/*metadata*/, value)

而NonLocalReturnControl的源码为:

class NonLocalReturnControl[@specialized T](val key: AnyRef, val value: T) extends ControlThrowable {    final override def fillInStackTrace(): Throwable = this}

可以看到NonLocalReturnControl异常继承了Throwable,并且为了提升性能重写了fillInStackTrace不填入堆栈信息。这样一来,如果我们在代码中为了保护代码不crash而这样写:

def fun(n:Int):String = {    try {        for(i <- 0 to n){            if(i < 5){            }else{                return "gt"            }        }        ""    }catch{        case t:Throwable => return t.toString    }}

最终得到的结果字符串则为scala.runtime.NonLocalReturnControl,并不是我们预期的结果。

5.应当怎么做

实际开发中我们会经常遇到貌似必须使用return的时候,那应该怎么办呢?首先,scala既然提供了return关键字,说明它并不是禁止使用,而是需要考虑清楚是否必须这么做。在scala认为,所有的需要使用return来break的循环,都是可以通过转化为递归来替代的,并且性能方面scala也专门为递归做了优化。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 照片粘玻璃上怎么办啊 个人3月旅游签证怎么办 澳洲签证拒签了怎么办 我想买房子可是没钱怎么办 微信身份证17位怎么办 身份证后4位泄露怎么办 车牌照掉了一个怎么办 车牌螺丝孔坏了怎么办 借了贷款还不起怎么办 谷歌验证码丢了怎么办 谷歌验证码错误怎么办 未满16岁怎么办银行卡 身份证在北京丢了怎么办 出国前护照丢了怎么办 在美国护照丢了怎么办 护照上照片太丑怎么办 小额贷还不起了怎么办 护照不到6个月怎么办 出国的护照是怎么办的 快递被退回去了怎么办 枫叶卡过期9年怎么办? l签去台湾怎么办入台证 导游证考过了怎么办 在澳洲护照丢了怎么办 在韩国护照丢了怎么办 回国前护照丢了怎么办 在韩国护照掉了怎么办 在机场护照丢了怎么办 在泰国掉了护照,怎么办 在蘇梅护照丢了怎么办 护照不小心撕了怎么办 旧护照过期丢了怎么办 超跑遇到减速带怎么办 微信被盗用了怎么办 手机微信被盗号怎么办 身份证办了5张卡怎么办 贷款合同不给我怎么办 欠了手机贷的钱怎么办 借民间贷款不还怎么办 民间借贷跑路了怎么办 拿到单程证后该怎么办