Scala基础教程

article/2025/10/14 14:03:00

简介

Scala是一种结合了面向对象和函数式编程的、静态类型的高级编程语言。
Scala代码被编译成.class文件,运行在Java虚拟机(JVM)上,可以调用Java类库。

官方网站:https://www.scala-lang.org/
官方文档:https://docs.scala-lang.org/

  • Scala语言规范
  • Scala标准库
  • 代码风格指南

官方教程:

  • Tour of Scala
  • Scala Book

在线运行环境:

  • Scastie
  • Scala在线工具

sbt构建工具:https://www.scala-sbt.org/index.html

安装

第1步:安装Java

由于Scala运行在JVM上,因此首先要安装JDK并配置JAVA_HOME环境变量。可从Oracle Java或AdoptOpenJDK下载。

第2步:安装Scala

下载地址:https://www.scala-lang.org/download/all.html

下载Scala

要使用IDE编辑Scala,可安装IntelliJ IDEA的Scala插件或VSCode的Metals插件

第3步:配置环境变量

将SCALA_HOME环境变量设置为Scala安装/解压目录,并将$SCALA_HOME/bin目录添加到PATH环境变量。例如,在~/.bashrc文件末尾增加:

export SCALA_HOME=/usr/local/scala-2.13.8
export PATH=$PATH:$SCALA_HOME/bin

之后执行source ~/.bashrc或重启终端,即可使用scala和scalac命令:

$ scala -version
Scala code runner version 2.13.8 -- Copyright 2002-2021, LAMP/EPFL and Lightbend, Inc.
$ scalac -version
Scala compiler version 2.13.8 -- Copyright 2002-2021, LAMP/EPFL and Lightbend, Inc.

Hello, world

Scala的 “Hello, world” 程序如下:

object Hello {def main(args: Array[String]) = {println("Hello, world!")}
}

另一种写法:

object Hello extends App {println("Hello, world!")
}

将代码保存到Hello.scala文件,使用scalac命令编译:

$ scalac Hello.scala

该命令将生成两个文件:Hello.class和Hello$.class。这些和使用javac创建的字节码文件相同,可以在JVM上运行。使用scala命令运行Hello程序:

$ scala Hello
Hello, world!

Scala REPL

Scala REPL (“Read-Evaluate-Print-Loop”)是一个命令行解释器,可以将其用作playground来测试Scala代码(相当于Python的IDLE)。

在命令行输入scala即可启动REPL会话:

$ scala
Welcome to Scala 2.13.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_312).
Type in expressions for evaluation. Or try :help.scala> 

输入:help查看帮助,输入:quit退出。

在REPL中可以输入Scala表达式:

scala> val x = 1
val x: Int = 1scala> val y = x + 1
val y: Int = 2

两种类型的变量

Scala有两种类型的变量:

  • val是不可变变量,类似于Java中的final,应该是首选
  • var创建一个可变变量,只有在有特定原因时才应该使用它

例如:

val x = 1   // 不可变
var y = 0   // 可变

声明变量类型

在Scala中创建变量时通常不声明变量类型,Scala会自动推断类型:

val x = 1
val s = "a string"
val p = new Person("Regina")

这一特性称为类型推断,有助于保持代码简洁。也可以显式声明变量类型,但通常没有必要:

val x: Int = 1
val s: String = "a string"
val p: Person = new Person("Regina")

控制结构

if/else

Scala的if/else控制结构与其他语言类似:

if (test1) {doA()
} else if (test2) {doB()
} else if (test3) {doC()
} else {doD()
}

但是,与Java和其他语言不同的是,if/else结构返回一个值,因此可以将其用作三元运算符:

val x = if (a < b) a else b

match表达式

Scala的match表达式类似于Java的switch语句:

val result = i match {case 1 => "one"case 2 => "two"case _ => "not 1 or 2"
}

match表达式不仅限于整数,它可以与任何数据类型一起使用:

val booleanAsString = b match {case true => "true"case false => "false"
}

下面是一个将match用作方法体的示例,与多种不同的类型进行匹配:

def getClassAsString(x: Any):String = x match {case s: String => s + " is a String"case i: Int => "Int"case f: Float => "Float"case l: List[_] => "List"case p: Person => "Person"case _ => "Unknown"
}

(这里是判断x的类型而不是具体值,相当于Java 14的instanceof模式匹配和Java 17的switch模式匹配)

try/catch

Scala的try/catch控制结构用于捕获异常,类似于Java,但其语法与match表达式一致:

try {writeToFile(text)
} catch {case fnfe: FileNotFoundException => println(fnfe)case ioe: IOException => println(ioe)
}

for循环和表达式

Scala的for循环有三种形式:

// for-in
for (arg <- args) println(arg)// "x to y" syntax
for (i <- 0 to 5) println(i)// "x to y by" syntax
for (i <- 0 to 10 by 2) println(i)

注意:to后面的上界是包含的!

可以在for循环中添加yield关键字来创建for表达式(相当于Python的列表推导式)。下面是一个将序列1~5中的每个值加倍的for表达式:

scala> val x = for (i <- 1 to 5) yield i * 2
val x: IndexedSeq[Int] = Vector(2, 4, 6, 8, 10)

下面是一个迭代字符串列表的for表达式:

val fruits = List("apple", "banana", "lime", "orange")val fruitLengths = for {f <- fruitsif f.length > 4
} yield f.length
// val fruitLengths: List[Int] = List(5, 6, 6)

从字面上即可理解代码的含义。

while和do/while

Scala的whiledo/while循环语法如下:

// while loop
while (condition) {statement
}// do-while
do {statement
} while (condition)

下面是一个Scala类的例子:

class Person(var firstName: String, var lastName: String) {def printFullName() = println(s"$firstName $lastName")
}

这是使用该类的方式:

val p = new Person("Julia", "Kern")
println(p.firstName)
p.lastName = "Manes"
p.printFullName()

注意,不需要创建 “get” 和 “set” 方法来访问类中的字段。

方法

像其他OOP语言一样,Scala类也有方法。Scala方法的语法如下:

def sum(a: Int, b: Int): Int = a + b
def concatenate(s1: String, s2: String): String = s1 + s2

不必声明方法的返回类型,因此这两个方法等价于

def sum(a: Int, b: Int) = a + b
def concatenate(s1: String, s2: String) = s1 + s2

这是调用方法的方式:

val x = sum(1, 2)
val y = concatenate("foo", "bar")

特质(Traits)

Scala的特质(traits)类似于Java的接口,可以将代码分解为小的模块化单元。例如,给定三个trait:

trait Speaker {def speak(): String  // has no body, so it’s abstract
}trait TailWagger {def startTail(): Unit = println("tail is wagging")def stopTail(): Unit = println("tail is stopped")
}trait Runner {def startRunning(): Unit = println("I’m running")def stopRunning(): Unit = println("Stopped running")
}

可以创建一个扩展(extend)所有这些trait的Dog类,同时实现speak方法:

class Dog(name: String) extends Speaker with TailWagger with Runner {def speak(): String = "Woof!"
}

类似地,Cat类覆盖了trait方法:

class Cat extends Speaker with TailWagger with Runner {def speak(): String = "Meow"override def startRunning(): Unit = println("Yeah ... I don’t run")override def stopRunning(): Unit = println("No need to stop")
}

集合类

虽然可以在Scala中使用Java集合类,但强烈建议学习基本的Scala集合类:ListListBufferVectorArrayBufferMapSet。Scala 集合类的一大好处是它们提供了许多强大的方法,可以使用这些方法来简化代码。

创建列表

Scala提供了很多创建列表的方法,例如:

scala> val nums = List.range(0, 10)
val nums: List[Int] = List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)scala> val nums = (1 to 10 by 2).toList
val nums: List[Int] = List(1, 3, 5, 7, 9)scala> val letters = ('a' to 'f').toList
val letters: List[Char] = List(a, b, c, d, e, f)scala> val letters = ('a' to 'f' by 2).toList
val letters: List[Char] = List(a, c, e)

序列方法

给定两个列表:

val nums = (1 to 10).toList
val names = List("joel", "ed", "chris", "maurice")

foreach方法:

scala> names.foreach(println)
joel
ed
chris
maurice

filter方法:

scala> nums.filter(_ < 4).foreach(println)
1
2
3

map方法:

scala> val doubles = nums.map(_ * 2)
val doubles: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)scala> val capNames = names.map(_.capitalize)
val capNames: List[String] = List(Joel, Ed, Chris, Maurice)scala> val lessThanFive = nums.map(_ < 5)
val lessThanFive: List[Boolean] = List(true, true, true, true, false, false, false, false, false, false)

foldLeft方法(相当于Python的functools.reduce()函数):

scala> nums.foldLeft(0)(_ + _)
val res18: Int = 55scala> nums.foldLeft(1)(_ * _)
val res19: Int = 3628800

第一个例子求nums中所有数字的和,第二个例子求nums中所有数字的积。

详细介绍见Scala Book - Scala Collections和Overview - Scala Collections。

元组

元组可以将不同类型的元素放在一个小容器中。一个元组可以包含2~22个值,并且所有值都可以具有不同的类型。例如,下面是一个包含IntDoubleString三种类型的元组:

(11, 11.0, "Eleven")

其类型是Tuple3

元组在很多地方都很方便。例如,可以从方法中返回一个元组:

def getAaplInfo(): (String, BigDecimal, Long) = {// get the stock symbol, price, and volume("AAPL", BigDecimal(123.45), 101202303L)
}

之后可以将方法的结果赋值给一个变量:

val t = getAaplInfo()

通过数字前面加下划线来访问元组的值:

scala> t._1
val res23: String = AAPLscala> t._2
val res24: BigDecimal = 123.45scala> t._3
val res25: Long = 101202303

下面的例子将元组中的字段赋值给变量(类似于Python的元组赋值):

scala> val (symbol, price, volume) = t
val symbol: String = AAPL
val price: BigDecimal = 123.45
val volume: Long = 101202303

元组非常适合快速、临时地将一些东西组合在一起。如果发现多次使用相同的元组,则声明一个专用的case类可能很有用。例如:

case class StockInfo(symbol: String, price: BigDecimal, volume: Long)

http://chatgpt.dhexx.cn/article/HEDIdZm2.shtml

相关文章

scala php,Scala 教程

Scala 教程 Scala 是一门多范式(multi-paradigm)的编程语言&#xff0c;设计初衷是要集成面向对象编程和函数式编程的各种特性。 Scala 运行在Java虚拟机上&#xff0c;并兼容现有的Java程序。 Scala 源代码被编译成Java字节码&#xff0c;所以它可以运行于JVM之上&#xff0c;…

Scala详细教程

Scala详细教程 目录 Scala详细教程 1.Scala 介绍 1.1 什么是 Scala Scala 1.2 为什么要学 Scala 2.开发环境准备 2.1 ScalaSDK 安装 2.1.1Window 下安装 ScalaSDK 2.1.2Linux 下安装 ScalaSDK 2.2 IDEA 安装 2.3 IDEAScala 插件的离线安装 2.4 IDEA 创建 HelloScala…

Scala教程

1. 基础语法 Scala语言是基于Java虚拟机运行的&#xff0c;所以基本的语法和Java是没有区别的。但是为了简化Java的开发以及融合其他的编程语言的优点和特性&#xff0c;Scala在基本的语法上做了大量的修改和优化&#xff0c;让程序员开发起来更简单&#xff0c;方便&#xff…

Scala教程-详细全部

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a;https://blog.csdn.net/qq_39346903/article/details/113562823 文章目录 第1章 Scala入门1.1 概述1.1.1 为什么学习Scala1.…

单工,半双工和全双工有何区别和联系?

单工、半双工和全双工是电信计算机网络中的三种通信信道。这些通信信道可以提供信息传达的途径。通信信道可以是物理传输介质或通过多路复用介质的逻辑连接。物理传输介质是指能够传播能量波的材料物质&#xff0c;例如数据通信中的导线。并且逻辑连接通常指电路交换连接或分组…

单工、半双工及全双工之间的区别

1、单工数据传输只支持数据在一个方向上传输&#xff1b;在同一时间只有一方能接受或发送信息&#xff0c;不能实现双向通信&#xff0c;举例&#xff1a;电视&#xff0c;广播。 2、半双工数据传输允许数据在两个方向上传输,但是,在某一时刻,只允许数据在一个方向上传输,它实…

全双工、半双工、单工有什么区别!

什么是全双工&#xff1f; 全双工&#xff1a;&#xff08;Full Duplex&#xff09;是通讯传输的一个术语。通信允许数据在两个方向上同时传输&#xff0c;它在能力上相当于两个单工通信方式的结合。全双工指可以同时&#xff08;瞬时&#xff09;进行信号的双向传输&#xff0…

三种通信方式——单工、半双工和双工通信

数据通常是在两个站&#xff08;点对点&#xff09;之间进行传输&#xff0c;按照数据流的方向可分为三种传输模式&#xff1a;单 工、半双工、全双工。 一、单工通信&#xff08;simplex&#xff09; 单工通信只支持信号在一个方向上传输&#xff08;正向或反向&#xff09…

图文并茂~ 详解交换机中的半双工与全双工网络知识

很多学习网络知识的朋友在配置交换机时&#xff0c;时常会看到半双工与全双工的功能&#xff0c;今天带大家一起来了解下什么是半双工与全双工。 早期的网络设备HUB&#xff08;集线器&#xff09;就是半双工&#xff0c;目前基本没有人用了&#xff0c;而现在用的SWITCH&…

[网络管理]全双工与半双工的区别

同事说新办公室的网络一直不稳定&#xff0c;经常掉线延迟。检查进口线路和更换转接网线。都无法解决问题。 估计是不是进口网线中一根或者2根短路&#xff0c;那就修改下网卡属性吧。把自适应改成全双工10M模式&#xff0c;测试OK。 全双工传输 英文写法是:Full&#xff0d;Du…

单工通信、半双工通信和全双工通信

数据通信中&#xff0c;数据在线路上的传送方式可以分为 单工通信、 半双工通信和 全双工通信三种。 ewlw半双工通信&#xff1a;半双工通信是指数据可以沿两个方向传送&#xff0c;但同一时刻一个 半双工总线结构 信道只允许单方向传送&#xff0c;因此又被称为双向交替通信。…

比较全面的HTTP和TCP网络传输的单工、全双工和半双工

文章目录 单工、全双工、半双工1. 单工2. 半双工3. 全双工 HTTP协议的工作模式TCP协议的工作模式 本文参考&#xff1a; 图解网络传输单工、半双工、全双工 - 知乎 (zhihu.com) 问&#xff1a;HTTP是单工的还是双工的还是半双工的 - 简书 (jianshu.com) 关于TCP全双工模式的解释…

简析全双工与半双工的区别

全双工传输英文写法是:Full&#xff0d;Duplex Transmissions 是指交换机在发送数据的同时也能够接收数据&#xff0c;两者同步进行&#xff0c;这好像我们平时打电话一样&#xff0c;说话的同时也能够听到对方的声音。目前的交换机都支持全双工。 全双工的好处在于迟延小&…

全双工与半双工的区别

全双工传输英文写法是:Full&#xff0d;Duplex Transmissions 是指交换机在发送数据的同时也能够接收数据&#xff0c;两者同步进行&#xff0c;这好像我们平时打电话一样&#xff0c;说话的同时也能够听到对方的声音。目前的交换机都支持全双工。 全双工的好处在于迟延小&…

全双工、半双工和单工

一&#xff0c;单工、半双工和全双工的区别&#xff1a; 在串行通信中&#xff0c;数据通常是在两个终端&#xff08;如电脑和外设&#xff09;之间进行传送&#xff0c;根据数据流的传输方向可分为3种基本传送方式&#xff1a;单工、半双工和全双工。这3种传输方式的示意图和区…

单工,半双工和和全双工通讯的概念

单工&#xff1a;数据传输只支持数据在一个方向上传输&#xff1b; 半双工&#xff1a;允许数据在两个方向上传输&#xff0c;但某一时刻只允许数据在一个方向上传输&#xff0c;实际上是一种切换方向的单工通信&#xff0c;不需要独立的接收端和发送端&#xff0c;两者可合并…

单工、半双工和全双工的区别

--------------------------------------------- -- 时间&#xff1a;2018-11-06 -- 创建人&#xff1a;Ruo_Xiao -- 邮箱&#xff1a;xclsoftware163.com --------------------------------------------- 一、单工 1、数据只在一个方向上传输&#xff0c;不能实现双方通信。…

单工、双工、半双工、全双工通信常识

根据通信双方的分工和信号传输方向可将通信分为三种方式&#xff1a;单工、半双工与全双工。 单工通信&#xff0c;指通信双方设备中发送器与接收器分工明确&#xff0c;只能在由发送器向接收器的单一固定方向上传送数据&#xff0c;并且不能实现双向通信&#xff0c;例如&…

网络传输单工、半双工、全双工的解读

来源 在网络传输中&#xff0c;数据在线路上的传送方式可以分为单工通信、半双工通信和全双工通信三种。以下我们将通过简单的叙述方式&#xff0c;配图了解这三种方式的定义和区别。 一、单工 定义&#xff1a;单工数据传输只支持数据在一个方向上传输。 举例&#xff1a;意思…

单工通信、半双工通信和全双工通信的区别

对于点对点之间的通信&#xff0c;按照消息传送的方向与时间关系&#xff0c;通信方式可分为单工通信、半双工通信及全双工通信三种。 一、单工通信 单工通信&#xff08;Simplex Communication&#xff09;是指消息只能单方向传输的工作方式。 在单工通信中&#xff0c;通信…