百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

有趣的 Scala 语言:简洁的 Scala 语法

itomcoil 2025-02-07 17:49 9 浏览

一、Scala开发环境

搭建Scala 开发环境,一是在IntelliJ IDEA 上安装Scala 插件和安装Scala SDK,具体操作步骤可以参考Scala专栏文章。

二是通过Scala RELP(Read-Eval-Print Loop)交互式环境,该交互式环境适合代码简单调试,不太适合进行应用开发。

二、变量和函数

定义变量时没有指定变量类型。这是否意味着 Scala 是和 Python 或者 Ruby 一样的动态类型语言呢?恰恰相反,Scala 是严格意义上的静态类型语言,由于其采用了先进的类型推断(Type Inference)技术,程序员不需要在写程序时显式指定类型,编译器会根据上下文推断出类型信息。比如变量 x被赋值为 0,0 是一个整型,所以 x的类型被推断出为整型。当然,Scala 语言也允许显示指定类型,如变量 x1,y1的定义。一般情况下,我们应尽量使用 Scala 提供的类型推断系统使代码看上去更加简洁。

另一个发现是程序语句结尾没有分号,这也是 Scala 中约定俗成的编程习惯。大多数情况下分号都是可省的,如果你需要将两条语句写在同一行,则需要用分号分开它们。

函数的定义也非常简单,使用关键字 def,后跟函数名和参数列表,如果不是递归函数可以选择省略函数返回类型。Scala 还支持定义匿名函数,匿名函数由参数列表,箭头连接符和函数体组成。函数在 Scala 中属于一级对象,它可以作为参数传递给其他函数,可以作为另一个函数的返回值,或者赋给一个变量。在下面的示例代码中,定义的匿名函数被赋给变量 cube。匿名函数使用起来非常方便,比如 List对象中的一些方法需要传入一个简单的函数作为参数,我们当然可以定义一个函数,然后再传给 List对象中的方法,但使用匿名函数,程序看上去更加简洁。


// 定义函数

def square(x: Int): Int = x * x

// 如果不是递归函数,函数返回类型可省略

def sum_of_square(x: Int, y: Int) = square(x) + square(y)

sum_of_square(2, 3)


// 定义匿名函数

val cube = (x: Int) => x * x *x

cube(3)

// 使用匿名函数,返回列表中的正数

List(-2, -1, 0, 1, 2, 3).filter(x => x > 0)


让我们再来和 Java 中对应的函数定义语法比较一下。首先,函数体没有像 Java 那样放在 {}里。Scala 中的一条语句其实是一个表达式,函数的执行过程就是对函数体内的表达式的求值过程,最后一条表达式的值就是函数的返回值。如果函数体只包含一条表达式,则可以省略 {}。其次,没有显示的 return语句,最后一条表达式的值会自动返回给函数的调用者。

和 Java 不同,在 Scala 中,函数内部还可以定义其他函数。比如上面的程序中,如果用户只对 sum_of_square 函数感兴趣,则我们可以将 square 函数定义为内部函数,实现细节的隐藏。


定义内部函数:


三、流程控制语句

复杂一点的程序离不开流程控制语句,Scala 提供了用于条件判断的 if else和表示循环的 while。和 Java 中对应的条件判断语句不同,Scala 中的 if else是一个表达式,根据条件的不同返回相应分支上的值。比如下面例子中求绝对值的程序,由于 Scala 中的 if else是一个表达式,所以不用像 Java 那样显式使用 return返回相应的值。


使用 if else 表达式:

def abs(n: Int): Int = if (n > 0) n else -n


和 Java 一样,Scala 提供了用于循环的 while 语句,在下面的例子中,我们将借助 while 循环为整数列表求和。

使用 while 为列表求和:

def sum(xs: List[Int]) = {

var total = 0

var index = 0

while (index < xs.size) {

total += xs(index)

index += 1

}

total

}


上述程序是习惯了 Java 或 C++ 的程序员想到的第一方案,但仔细观察会发现有几个问题:首先,使用了 var定义变量,我们在前面说过,尽量避免使用 var。其次,这个程序太长了,第一次拿到这个程序的人需要对着程序仔细端详一会:程序首先定义了两个变量,并将其初始化为 0,然后在 index小于列表长度时执行循环,在循环体中,累加列表中的元素,并将 index加 1,最后返回最终的累加值。直到这时,这个人才意识到这个程序是对一个数列求和。


让我们换个角度,尝试用递归的方式去思考这个问题,对一个数列的求和问题可以简化为该数列的第一个元素加上由后续元素组成的数列的和,依此类推,直到后续元素组成的数列为空返回 0。具体程序如下,使用递归,原来需要 9 行实现的程序现在只需要两行,而且程序逻辑看起来更清晰,更易懂。


使用递归对数列求和:

//xs.head 返回列表里的头元素,即第一个元素

//xs.tail 返回除头元素外的剩余元素组成的列表

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


有没有更简便的方式呢?答案是肯定的,我们可以使用列表内置的一些方法达到同样的效果:


上述使用了规约操作。

规约操作是对容器的元素进行两两运算,将其规约为一个值。最常见的规约方式使 reduce,它接受一个二元函数 f 作为参数,首先将 f 作用在某两个元素上并返回一个值,然后再将 f 作用在上一个返回值和容器的下一个元素上,再返回一个值,依次类推,最后容器中的所有值会被规约为一个值。


list map (_.toString) reduce((x,y)=>s"f($x,$y)")

上面这行代码:先通过 map 操作将List[Int] 转化成 List[String],也就是把列表中的每个元素从 Int 类型转换成 String 类型,然后对这个字符串进行自定义规约,语句的执行结果清楚地展示了 reduce的过程。


事实上,List 已经为我们提供了 sum 方法,在实际应用中,我们应该使用该方法,而不是自己定义一个。作者只是希望通过上述例子,让大家意识到 Scala 虽然提供了用于循环的 while 语句,但大多数情况下,我们有其他更简便的方式能够达到同样的效果。



四、如何运行 Scala 程序?

在运行方式上,Scala 又一次体现出了它的灵活性。它可以被当作一种脚本语言执行,也可以像 Java 一样,作为应用程序执行。


作为脚本执行:

我们可以将 Scala 表达式写在一个文件里,比如 Hello.scala。在命令行中直接输入 scala Hello.scala就可得到程序运行结果。

Hello.scala 代码:

println("Hello Rickie!")


作为应用程序执行:

作为应用程序执行时,我们需要在一个单例对象中定义入口函数 main,经过编译后就可以执行该应用程序了。

object HelloRickie {

def main(args: Array[String]): Unit = {

println("Hello Rickie!")

}

}


Scala 还提供了一个更简便的方式,直接继承另一个对象 App,无需定义 main方法,编译即可运行。


五、结束语

本文为大家介绍了 Scala 的基本语法,相比 Java,Scala 的语法更加简洁,比如 Scala 的类型推断可以省略程序中绝大多数的类型声明,短小精悍的匿名函数可以方便的在函数之间传递,还有各种在 Scala 社区约定俗成的习惯,比如省略的分号以及函数体只有一条表达式时的花括号,这一切都帮助程序员写出更简洁,更优雅的程序。

相关推荐

Excel新函数TEXTSPLIT太强大了,轻松搞定数据拆分!

我是【桃大喵学习记】,欢迎大家关注哟~,每天为你分享职场办公软件使用技巧干货!最近我把WPS软件升级到了版本号:12.1.0.15990的最新版本,最版本已经支持文本拆分函数TEXTSPLIT了,并...

Excel超强数据拆分函数TEXTSPLIT,从入门到精通!

我是【桃大喵学习记】,欢迎大家关注哟~,每天为你分享职场办公软件使用技巧干货!今天跟大家分享的是Excel超强数据拆分函数TEXTSPLIT,带你从入门到精通!TEXTSPLIT函数真是太强大了,轻松...

看完就会用的C++17特性总结(c++11常用新特性)

作者:taoklin,腾讯WXG后台开发一、简单特性1.namespace嵌套C++17使我们可以更加简洁使用命名空间:2.std::variant升级版的C语言Union在C++17之前,通...

plsql字符串分割浅谈(plsql字符集设置)

工作之中遇到的小问题,在此抛出问题,并给出解决方法。一方面是为了给自己留下深刻印象,另一方面给遇到相似问题的同学一个解决思路。如若其中有写的不好或者不对的地方也请不加不吝赐教,集思广益,共同进步。遇到...

javascript如何分割字符串(javascript切割字符串)

javascript如何分割字符串在JavaScript中,您可以使用字符串的`split()`方法来将一个字符串分割成一个数组。`split()`方法接收一个参数,这个参数指定了分割字符串的方式。如...

TextSplit函数的使用方法(入门+进阶+高级共八种用法10个公式)

在Excel和WPS新增的几十个函数中,如果按实用性+功能性排名,textsplit排第二,无函数敢排第一。因为它不仅使用简单,而且解决了以前用超复杂公式才能搞定的难题。今天小编用10个公式,让你彻底...

Python字符串split()方法使用技巧

在Python中,字符串操作可谓是基础且关键的技能,而今天咱们要重点攻克的“堡垒”——split()方法,它能将看似浑然一体的字符串,按照我们的需求进行拆分,极大地便利了数据处理与文本解析工作。基本语...

go语言中字符串常用的系统函数(golang 字符串)

最近由于工作比较忙,视频有段时间没有更新了,在这里跟大家说声抱歉了,我尽快抽些时间整理下视频今天就发一篇关于go语言的基础知识吧!我这我工作中用到的一些常用函数,汇总出来分享给大家,希望对...

无规律文本拆分,这些函数你得会(没有分隔符没规律数据拆分)

今天文章来源于表格学员训练营群内答疑,混合文本拆分。其实拆分不难,只要规则明确就好办。就怕规则不清晰,或者规则太多。那真是,Oh,mygod.如上图所示进行拆分,文字表达实在是有点难,所以小熊变身灵...

Python之文本解析:字符串格式化的逆操作?

引言前面的文章中,提到了关于Python中字符串中的相关操作,更多地涉及到了字符串的格式化,有些地方也称为字符串插值操作,本质上,就是把多个字符串拼接在一起,以固定的格式呈现。关于字符串的操作,其实还...

忘记【分列】吧,TEXTSPLIT拆分文本好用100倍

函数TEXTSPLIT的作用是:按分隔符将字符串拆分为行或列。仅ExcelM365版本可用。基本应用将A2单元格内容按逗号拆分。=TEXTSPLIT(A2,",")第二参数设置为逗号...

Excel365版本新函数TEXTSPLIT,专攻文本拆分

Excel中字符串的处理,拆分和合并是比较常见的需求。合并,当前最好用的函数非TEXTJOIN不可。拆分,Office365于2022年3月更新了一个专业函数:TEXTSPLIT语法参数:【...

站长在线Python精讲使用正则表达式的split()方法分割字符串详解

欢迎你来到站长在线的站长学堂学习Python知识,本文学习的是《在Python中使用正则表达式的split()方法分割字符串详解》。使用正则表达式分割字符串在Python中使用正则表达式的split(...

Java中字符串分割的方法(java字符串切割方法)

技术背景在Java编程中,经常需要对字符串进行分割操作,例如将一个包含多个信息的字符串按照特定的分隔符拆分成多个子字符串。常见的应用场景包括解析CSV文件、处理网络请求参数等。实现步骤1.使用Str...

因为一个函数strtok踩坑,我被老工程师无情嘲笑了

在用C/C++实现字符串切割中,strtok函数经常用到,其主要作用是按照给定的字符集分隔字符串,并返回各子字符串。但是实际上,可不止有strtok(),还有strtok、strtok_s、strto...