返回顶部
首页 > 资讯 > 前端开发 > html >怎么使用Scala语言
  • 452
分享到

怎么使用Scala语言

2024-04-02 19:04:59 452人浏览 八月长安
摘要

这篇文章主要讲解了“怎么使用Scala语言”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用Scala语言”吧!为什么递归会受到忽视为 了回答这一问题,

这篇文章主要讲解了“怎么使用Scala语言”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用Scala语言”吧!

为什么递归会受到忽视

为 了回答这一问题,必须先说到编程范式。在所有的编程范式中,面向对象编程(Object-Oriented  Programming)无疑是***的赢家。看看网上的招聘启事,无一例外,会要求应聘者熟练掌握面向对象编程。但其实面向对象编程并不是一种严格意义上  的编程范式,严格意义上的编程范式分为:命令式编程(Imperative Programming)、函数式编程(Functional  Programming)和逻辑式编程(Logic  Programming)。面向对象编程只是上述几种范式的一个交叉产物,更多的还是继承了命令式编程的基因。遗憾的是,在长期的教学过程中,只有命令式   编程得到了强调,那就是程序员要告诉计算机应该怎么做,而不是告诉计算机做什么。而递归则通过灵巧的函数定义,告诉计算机做什么。因此在使用命令式编程思   维的程序中,不得不说,这是现在多数程序采用的编程方式,递归出镜的几率很少,而在函数式编程中,大家可以随处见到递归的方式。下面,我们就通过实例,为  大家展示递归如何作为一种普遍方式,来解决编程问题的。

一组简单的例子

如何为一组整数数列求和?按照通常命令式编程的思 维,我们会采用循环,依次遍历列表中的每个元素进行累加,最终给出求和结果。这样的程序不难写,稍  微具备一点编程经验的人在一分钟之内就能写出来。这次我们换个思维,如何用递归的方式求和?为此,我们不妨把问题简化一点,假设数列包含 N  个数,如果我们已经知道了后续 N – 1 个数的和,那么整个数列的和即为***个数加上后续 N – 1 个数的和,依此类推,我们可以以同样的方式为  N – 1  个数继续求和,直到数列为空,显然,空数列的和为零。听起来复杂,事实上我们可以用一句话来总结:一个数列的和即为数列中的***个数加上由后续数字组成的  数列的和。现在,让我们用 Scala 语言把这个想法表达出来。

清单 1. 数列求和

//xs.head 返回列表里的头元素,即***个元素 //xs.tail 返回除头元素外的剩余元素组成的列表 def sum(xs: List[Int]): Int =  if (xs.isEmpty) 0 else xs.head + sum(xs.tail)

大家可以看到,我们只使用一行程序,就将上面求和的方法表达出来了,而且这一行程序看上去简单易懂。尽量少写代码,这也是 Scala  语言的设计哲学之一,较少的代码量意味着写起来更加容易,读起来更加易懂,同时代码出错的概率也会降低。同样的程序,使用 Scala  语言写出的代码量通常会比 Java 少一半甚至更多。

上述这个数列求和的例子并不是特别的,它代表了递归对于列表的一种普遍的处理方式,即对一个列表的操作,可转化为对***个元素,及剩余列表的相同操 作。比如我们可以用同样的方式求一个数列中的***值。我们假设已经知道了除***个元素外剩余数列的***值,那么整个数列的***值即为***个元素和剩余数列 ***值中的大者。这里需要注意的是对于一个空数列求***值是没有意义的,所以我们需要向外抛出一个异常。当数列只包含一个元素时,***值就为这个元素本 身,这种情况是我们这个递归的边界条件。一个递归算法,必须要有这样一个边界条件,否则会一直递归下去,形成死循环。

清单 2. 求***值

def max(xs: List[Int]): Int = {    if (xs.isEmpty)      throw new java.util.NoSuchElementException    if (xs.size == 1)      xs.head    else      if (xs.head > max(xs.tail)) xs.head else max(xs.tail) }v

同样的方式,我们也可以求一个数列中的最小值,作为一个练习,读者可下去自行实现。

让我们再看一个例子:如何反转一个字符串?比如给定一个字符串"abcd",经过反转之后变为 "dcba"。同样的,我们可以做一个大胆的假设,假设后续字符串已经反转过来,那么接上***个字符,整个字符串就反转过来了。对于一个只有一个字符的字符串,不需要反转,这是我们这个递归算法的边界条件。程序实现如下:

清单 3. 反转字符串

def reverse(xs: String): String = if (xs.length == 1) xs else reverse(xs.tail) + xs.head

***一个例子是经典的快速排序,读者可能会觉得这个例子算不上简单,但是我们会看到,使用递归的方式,再加上 Scala 简洁的语言特性,我们只需要短短几行程序,就可以实现快速排序算法。 快速排序算法的核心思想是:在一个无序列表中选择一个值,根据该值将列表分为两部分,比该值小的那一部分排在前面,比该值大的部分排在后面。对于这两部分 各自使用同样的方式进行排序,直到他们为空,显然,我们认为一个空的列表即为一个排好序的列表,这就是这个算法中的边界条件。为了方便起见,我们选择*** 个元素作为将列表分为两部分的值。程序实现如下:

清单 4. 快速排序

def quickSort(xs: List[Int]): List[Int] = {    if (xs.isEmpty) xs    else      quickSort(xs.filter(x=>x<xs.head)):::xs.head::quickSort(xs.filter(x=>x>xs.head)) }

当然,为了使程序更加简洁,作者在这里使用了列表中的一些方法:给列表增加一个元素,连接两个列表以及过滤一个列表,并在其中使用了 lambda 表达式。但这一切都使程序变得更符合算法的核心思想,更加易读。

尾递归

从上面的例子中我们可以看到,使用递归方式写出的程序通常通俗易懂,这其实代表这两种编程范式的不同,命令式编程范式倾向于使用循环,告诉计算机怎 么做,而函数式编程范式则使用递归,告诉计算机做什么。习惯于命令式编程范式的程序员还有一个担忧:相比循环,递归不是存在效率问题吗?每一次递归调用, 都会分配一个新的函数栈,如果递归嵌套很深,容易出现栈溢出的问题。比如下面计算阶乘的递归程序:

清单 5. 递归求阶乘

def factorial(n: Int): Int = if (n == 0) 1 else n * factorial(n - 1)

当递归调用 n &ndash; 1的阶乘时,由于需要保存前面的 n,必须分配一个新的函数栈,这样当 n很大时,函数栈将很快被耗尽。然而尾递归能帮我们解决这个问题,所谓尾递归是指在函数调用的***一步,只调用该递归函数本身,此时,由于无需记住其他变量,当前的函数栈可以被重复使用。上面的程序只需稍微改造一下,既可以变成尾递归式的程序,在效率上,和循环是等价的。

清单 6. 尾递归求阶乘

def factorial(n: Int): Int = {    @tailrec    def loop(acc: Int, n: Int): Int =      if (n == 0) acc else loop(n * acc, n - 1)      loop(1, n) }

在上面的程序中,我们在阶乘函数内部定义了一个新的递归函数,该函数***一步要么返回结果,要么调用该递归函数本身,所以这是一个尾递归函数。该函数多出一个变量 acc,每次递归调用都会更新该变量,直到递归边界条件满足时返回该值,即为***的计算结果。这是一种通用的将非尾递归函数转化为尾递归函数的方法,大家可多加练习,掌握这一方法。对于尾递归,Scala 语言特别增加了一个注释 @tailrec,该注释可以确保程序员写出的程序是正确的尾递归程序,如果由于疏忽大意,写出的不是一个尾递归程序,则编译器会报告一个编译错误,提醒程序员修改自己的代码。

一道面试题

也许有的读者看了上面的例子后,还是感到不能信服:虽然使用递归会让程序变得简洁易懂,但我用循环也一样可以实现,大不了多几行代码而已,而且我还 不用知道什么尾递归,写出的程序就是效率***的。那我们一起来看看下面这个问题:有趣的零钱兑换问题。题目大致如下:假设某国的货币有若干面值,现给一张 大面值的货币要兑换成零钱,问有多少种兑换方式。这个问题经常被各大公司作为一道面试题,不知难倒了多少同学,下面我给出该问题的递归解法,读者们可以试 试该问题的非递归解法,看看从程序的易读性,及代码数量上,两者会有多大差别。该问题的递归解法思路很简单:首先确定边界条件,如果要兑换的钱数为  0,那么返回 1,即只有一种兑换方法:没法兑换。这里要注意的是该问题计算所有的兑换方法,无法兑换也算一种方法。如果零钱种类为 0 或钱数小于  0,没有任何方式进行兑换,返回  0。我们可以把找零的方法分为两类:使用不包含***枚硬币(零钱)所有的零钱进行找零,使用包含***枚硬币(零钱)的所有零钱进行找零,两者之和即为所有 的找零方式。***种找零方式总共有 countChange(money, coins.tail)种,第二种找零方式等价为对于 money &ndash; conins.head进行同样的兑换,则这种兑换方式有 countChange(money - coins.head, coins)种,两者之和即为所有的零钱兑换方式。

清单 7. 零钱兑换问题的递归解法

def countChange(money: Int, coins: List[Int]): Int = {   if (money == 0)     1   else if (coins.size == 0 || money < 0)     0   else     countChange(money, coins.tail) + countChange(money - coins.head, coins) }

感谢各位的阅读,以上就是“怎么使用Scala语言”的内容了,经过本文的学习后,相信大家对怎么使用Scala语言这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 怎么使用Scala语言

本文链接: https://lsjlt.com/news/86448.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 怎么使用Scala语言
    这篇文章主要讲解了“怎么使用Scala语言”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用Scala语言”吧!为什么递归会受到忽视为 了回答这一问题,...
    99+
    2024-04-02
  • Scala的IF ELSE语句怎么使用
    这篇文章主要讲解了“Scala的IF ELSE语句怎么使用”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Scala的IF ELSE语句怎么使用”吧!Scala IF...ELSE 语句是通过...
    99+
    2023-06-19
  • Scala是一种什么语言
    这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相信很多人在Scala是一种什么语言问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Scala是一种什么语言”的疑惑有所帮助!接下来,请跟着小编一起来...
    99+
    2023-06-19
  • scala中怎么使用val语句和def语句
    本篇内容介绍了“scala中怎么使用val语句和def语句”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Scala 中使用 val 语句可以...
    99+
    2023-06-02
  • Scala Trait怎么使用
    这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相信很多人在Scala Trait怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Scala Trait怎么使用”的疑惑有所帮助!接下来...
    99+
    2023-06-19
  • Scala Option怎么使用
    本篇内容介绍了“Scala Option怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!  在Scala中Option类型样例类用来表...
    99+
    2023-06-02
  • scala集合怎么使用
    本篇内容主要讲解“scala集合怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“scala集合怎么使用”吧!List// 字符串列表val site: Lis...
    99+
    2023-06-02
  • Scala提取器怎么使用
    本篇内容主要讲解“Scala提取器怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala提取器怎么使用”吧!Scala 提取器是一个带有unapply方法的对象。unapply方法算是...
    99+
    2023-06-19
  • Scala for循环怎么使用
    本篇内容介绍了“Scala for循环怎么使用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!基本语法:变量,变量的定义:不可变:val a ...
    99+
    2023-06-02
  • 如何利用Scala语言开发Spark应用程序
    这篇文章主要介绍如何利用Scala语言开发Spark应用程序,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Spark内核是由Scala语言开发的,因此使用Scala语言开发Spark...
    99+
    2024-04-02
  • Scala学习系列(一)——Scala为什么是大数据第一高薪语言
    为什么是Scala 虽然在大数据领域Java的使用更普及,Python也有后来居上的势头,但Scala一直有着不可动摇的地位。我们熟悉的Spark,Kafka,Flink都是由Scala完成了其核心代码的开发。 所以掌握Scala...
    99+
    2020-10-19
    Scala学习系列(一)——Scala为什么是大数据第一高薪语言
  • 大数据开发语言用Scala还是Go好
    本篇内容介绍了“大数据开发语言用Scala还是Go好”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Scala是一种较旧且更成熟的编程语言,已...
    99+
    2023-06-15
  • 怎么使用GO语言
    这篇文章主要讲解了“怎么使用GO语言”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么使用GO语言”吧!什么是 GVMGo 语言版本管理器(GVM)是管理 Go 语言环境的开源工具。GVM ...
    99+
    2023-06-16
  • 怎么使用Python语言
    本篇内容介绍了“怎么使用Python语言”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、先回答这个问题为什么想学编程语言 在进一步阅读之前...
    99+
    2023-06-16
  • Scala方法与函数怎么使用
    本篇内容主要讲解“Scala方法与函数怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Scala方法与函数怎么使用”吧!Scala 有方法与函数,二者在语义上的区别很小。Scala 方法是...
    99+
    2023-06-19
  • Future怎么在Java与Scala中使用
    Future怎么在Java与Scala中使用?很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。Future很多同学可能会有疑问,Futrue跟异步编程有什么关系?从...
    99+
    2023-05-30
    java scala future
  • Java Scala泛型方法怎么使用
    本文小编为大家详细介绍“Java Scala泛型方法怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java Scala泛型方法怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1...
    99+
    2023-07-05
  • Java Scala面向对象怎么使用
    今天小编给大家分享一下Java Scala面向对象怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Scala...
    99+
    2023-07-06
  • 你知道Scala编程语言吗?Scala基础教程【建议收藏】
    系列文章目录 作者:i阿极 作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞...
    99+
    2023-09-01
    scala java 开发语言
  • Golang 与 Scala 在语言特性的差异
    go 和 scala 在语言特性上的差异在于:类型系统:go 采用静态类型系统,而 scala 采用混合类型系统。并发性:go 基于轻量级 goroutine,而 scala 使用基于 ...
    99+
    2024-05-12
    golang scala
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作