在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
1

是一个函数。

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

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

从以上两种分别使用和不使用 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.1
def sum1(ns: Int*): Int = ns.foldLeft(0)(add) //式3.2
12

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

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

直观感受式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))
}
1234

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

4.NonLocalReturnControl

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

return value
1

被编译成了

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

而NonLocalReturnControl的源码为:

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

可以看到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
}
}
12345678910111213

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

5.应当怎么做

实际开发中我们会经常遇到貌似必须使用return的时候,那应该怎么办呢?

首先,scala既然提供了 return 关键字,说明它并不是禁止使用,而是需要考虑清楚是否必须这么做。在scala认为,所有的需要使用 return 来 break 的循环,都是可以通过转化为递归来替代的,并且性能方面 scala 也专门为递归做了优化。

Scala 中为什么不建议用 return 关键字的更多相关文章

  1. Java中处理异常中return关键字

    Java中,执行try-catch-finally语句需要注意: 第一:return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂 ...

  2. 第2节 Scala中面向对象编程:7、继承的概念以及override和super关键字;8、isInstanceOf 和 asInstanceOf关键字

    6.3.   Scala面向对象编程之继承 6.3.1.     Scala中继承(extends)的概念 Scala 中,让子类继承父类,与 Java 一样,也是使用 extends 关键字: 继承 ...

  3. Programming In Scala笔记-第七章、Scala中的控制结构

    所谓的内建控制结构是指编程语言中可以使用的一些代码控制语法,如Scala中的if, while, for, try, match, 以及函数调用等.需要注意的是,Scala几乎所有的内建控制结构都会返 ...

  4. Scala学习(五)---Scala中的类

    Scala中的类 摘要: 在本篇中,你将会学习如何用Scala实现类.如果你了解Java或C++中的类,你不会觉得这有多难,并且你会很享受Scala更加精简的表示法带来的便利.本篇的要点包括: 1. ...

  5. Programming In Scala笔记-第十一章、Scala中的类继承关系

    本章主要从整体层面了解Scala中的类层级关系. 一.Scala的类层级 在Java中Object类是所有类的最终父类,其他所有类都直接或间接的继承了Object类.在Scala中所有类的最终父类为A ...

  6. [转] Scala 中的异步事件处理

    在任何并发性应用程序中,异步事件处理都至关重要.无论事件的来源是什么(不同的计算任务.I/O 操作或与外部系统的交互),您的代码都必须跟踪事件,协调为响应它们而执行的操作.应用程序可以采用两种基本方法 ...

  7. 异常处理机制中的return关键字

    Java中,执行try-catch-finally语句需要注意: 第一:return语句并不是函数的最终出口,如果有finally语句,这在return之后还会执行finally(return的值会暂 ...

  8. 大数据学习之Scala中main函数的分析以及基本规则(2)

    一.main函数的分析 首先来看我们在上一节最后看到的这个程序,我们先来简单的分析一下.有助于后面的学习 object HelloScala { def main(args: Array[String ...

  9. scala学习手记16 – scala中的static

    前面两节学了scala的对象和伴生对象,这两个在使用的时候很有些java的静态成员的意思. scala中没有静态字段和静态方法.静态成员会破坏scala所支持的完整的面向对象模型.不过可以通过伴生对象 ...

随机推荐

  1. 软工案例分析之OJ

    项目 内容 这个作业属于哪个课程 2021春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 案例分析作业要求 我在这个课程的目标是 和我的团队开发一个真正的软件,一起提升开发与合作的能力 这 ...

  2. jQuery入门看这一篇就够了

    一.选择器 1.基本 名称 用法 描述 #id $("#myDiv"); 根据给定的ID匹配一个元素 element $("div"); 根据给定的元素标签名匹 ...

  3. 面试题:让你捉摸不透的 Go reslice

    面试题: package main func a() []int { a1 := []int{3} a2 := a1[1:] return a2 } func main() { a() } 看到这个题 ...

  4. Day01_09_数据类型

    数据类型 数据类型分类 *基本数据类型 *引用数据类型 基本数据类型 --第一类 整数型 byte short int long --第二类 浮点型 float double --第三类 布尔型 bo ...

  5. yolov2算法浅见

    因为最近在复习yolo系列的算法,就借着这个机会总结一下自己对这个算法的理解,由于是第一次写算法类的博客,文中有什么错误和行文不通的地方还希望大家指正. yolov2与yolov1有很多改变. 最重要 ...

  6. 05- 移动端APP的分类 与对比webApp hybridApp nativeApp

    随着智能手机的普及,移动端应用几乎成为每个互联网产品的标配.在快速迭代的互联网战场中高效开发.低成本上线产品,是每个应用开发团队追求的目标.此时,选择合适的应用类型和开发模式便至关重要.移动应用可以粗 ...

  7. python 第三方库大全

    Python 作为程序员的宠儿,越来越得到人们的关注,使用 Python 进行应用程序开发的越来也多.那么,在 2013 年有哪些流行的 Python 项目呢?下面,我们一起来看下. https:// ...

  8. hdu4993(水题)

    题意:       x * a + y * b = c xyab都是正整数,给你a,b,c问有多少对xy组合满足等式. 思路:       水题,直接枚举其中一个,然后看求出的y是不是正整数就行了,第 ...

  9. ElasticSearch7.10.0入门学习

    ElasticSearch完成最关键的一个功能就是 大数据搜索 官网:https://www.elastic.co/cn/elasticsearch/ 简介 Elasticsearch 是一个分布式全 ...

  10. 【Redis】redis异步消息队列+Spring自定义注解+AOP方式实现系统日志持久化

    说明: SSM项目中的每一个请求都需要进行日志记录操作.一般操作做的思路是:使用springAOP思想,对指定的方法进行拦截.拼装日志信息实体,然后持久化到数据库中.可是仔细想一下会发现:每次的客户端 ...