- Scala的“味道”
- Overview 概述
- Hello, world
- The Scala REPL
- Two types of variables
- Declaring variable types
- Control structures
- if/else
- match expressions
- try/catch
- for loops and expressions
- while and do/while
- Classes
- Scala methods
- Traits
- Collections classes
- Populating lists
- Sequence methods
- Tuples
- What we haven’t shown
原文地址: https://docs.scala-lang.org/overviews/scala-book/prelude-taste-of-scala.html
在本书中,我们假设您以前使用过 Java 之类的语言,并准备好查看一系列 Scala 示例以了解该语言的外观。 尽管这不是 100% 必要的,但如果您已经下载并安装了 Scala,它也会有所帮助,这样您就可以在进行过程中测试示例。 您还可以使用 ScalaFiddle.io 在线测试这些示例。
Overview 概述在我们进入示例之前,这里有一些关于 Scala 的重要信息:
- 这是一种高级语言
- 它是静态类型的
- 它的语法简洁但仍然可读——我们称之为富有表现力
- 它支持面向对象编程 (OOP) 范式
- 它支持函数式编程 (FP) 范式
- 它有一个复杂的类型推断系统
- Scala 代码生成在 Java 虚拟机 (JVM) 上运行的 .class 文件
- 在 Scala 中使用 Java 库很容易
从《C 编程语言》这本书开始,以“Hello, world”示例开始编程书籍一直是一种传统,不要让人失望,这是在 Scala 中编写该示例的一种方式:
object Hello extends App {
println("Hello, world")
}
将该代码保存到名为 Hello.scala 的文件后,您可以使用scalac
编译它:
$ scalac Hello.scala
如果您是从 Java 来到 Scala,scalac 就像 javac,该命令会创建两个文件:
- Hello$.class
- Hello.class
这些与您使用 javac 创建的“.class”字节码文件相同,它们已准备好在 JVM 中运行。 使用 scala 命令运行 Hello 应用程序:
$ scala Hello
我们将在接下来的课程中分享更多“Hello, world”示例,因此我们暂时保留该介绍。
The Scala REPLScala REPL(“Read-Evaluate-Print-Loop”)是一个命令行解释器,您可以将其用作测试 Scala 代码的“操场”区域。 我们在这里很早就介绍了它,以便您可以将它与后面的代码示例一起使用。
要启动 REPL 会话,只需在您的操作系统命令行中输入 scala,您将看到如下内容:
$ scala
Welcome to Scala 2.13.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.
scala> _
因为 REPL 是一个命令行解释器,它只是坐在那里等待你输入一些东西。 在 REPL 中,您键入 Scala 表达式以查看它们是如何工作的:
scala> val x = 1
x: Int = 1
scala> val y = x + 1
y: Int = 2
如这些示例所示,在 REPL 中键入表达式后,它会在提示后的行中显示每个表达式的结果。
Two types of variablesScala 有两种类型的变量:
val
is an immutable variable — likefinal
in Java — and should be preferredvar
creates a mutable variable, and should only be used when there is a specific reason to use it- Examples:
val x = 1 //immutable
var y = 0 //mutable
Declaring variable types
在 Scala 中,您通常创建变量而不声明它们的类型:
val x = 1
val s = "a string"
val p = new Person("Regina")
当您这样做时,Scala 通常可以为您推断数据类型,如以下 REPL 示例所示:
scala> val x = 1
val x: Int = 1
scala> val s = "a string"
val s: String = a string
此功能称为类型推断,它是帮助保持代码简洁的好方法。 您还可以显式声明变量的类型,但这通常不是必需的:
如您所见,该代码看起来不必要地冗长。
Control structures这是 Scala 控制结构的快速浏览。
if/elseScala 的 if/else 控制结构与其他语言类似:
if (test1) {
doA()
} else if (test2) {
doB()
} else if (test3) {
doC()
} else {
doD()
}
然而,与Java和许多其他语言不同的是,if/else构造返回一个值,因此,除了其他功能外,你可以将它用作一个三元操作符:
val x = if (a "one"
case 2 => "two"
case _ => "not 1 or 2"
}
匹配表达式不仅限于整数,它可以用于任何数据类型,包括布尔值:
val booleanAsString = bool 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"
}
强大的匹配表达式是 Scala 的一大特色,我们将在本书后面分享更多示例。
try/catchScala 的 try/catch 控制结构可让您捕获异常。 它类似于Java,但其语法与匹配表达式一致:
try {
writeToFile(text)
} catch {
case fnfe: FileNotFoundException => println(fnfe)
case ioe: IOException => println(ioe)
}
for loops and expressions
Scala for
循环——我们在本书中通常将其写为 for 循环——看起来像这样:
for (arg names.foreach(println)
joel
ed
chris
maurice
这是一个filter
然后是一个foreach
方法
scala> nums.filter(_ val doubles = nums.map(_ * 2)
doubles: List[Int] = List(2, 4, 6, 8, 10, 12, 14, 16, 18, 20)
scala> val capNames = names.map(_.capitalize)
capNames: List[String] = List(Joel, Ed, Chris, Maurice)
scala> val lessThanFive = nums.map(_ nums.foldLeft(0)(_ + _)
res0: Int = 55
scala> nums.foldLeft(1)(_ * _)
res1: Int = 3628800
一旦您知道 foldLeft
的第一个参数是seed value,您就可以猜测第一个示例得出nums
中数字的总和,而第二个示例返回所有这些数字的乘积。
Scala 集合类有很多(很多!)更多方法可用,其中许多方法将在接下来的集合课程中演示,但希望这能让您了解它们的功能。
Tuples元组让您可以将不同的元素集合放在一个小容器中。 一个元组可以包含 2 到 22 个值,并且所有值都可以有不同的类型。 例如,这是一个包含三种不同类型(Int
、Double
和 String
)的元组:
(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()
一旦你有了一个元组变量,你就可以通过数字访问它的值,前面是下划线:
t._1
t._2
t._3
REPL 演示了访问这些字段的结果:
scala> t._1
res0: String = AAPL
scala> t._2
res1: scala.math.BigDecimal = 123.45
scala> t._3
res2: Long = 101202303
元组的值也可以使用模式匹配来提取。 在下一个示例中,元组内的字段被分配给变量symbol
、price
和volume
:
val (symbol, price, volume) = getAaplInfo()
REPL 再次演示了结果:
scala> val (symbol, price, volume) = getAaplInfo()
symbol: String = AAPL
price: scala.math.BigDecimal = 123.45
volume: Long = 101202303
当你想快速(和临时)将一些东西组合在一起的时候,元组是很好的。 如果您注意到多次使用相同的元组,那么声明一个专用的 case 类可能会很有用,例如:
case class StockInfo(symbol: String, price: BigDecimal, volume: Long)
What we haven’t shown
虽然这是 Scala 的旋风式介绍,大约有十页印刷,但还有很多东西我们还没有展示,包括:
- 字符串和内置数字类型
- 包装和进口
- 如何在 Scala 中使用 Java 集合类
- 如何在 Scala 中使用 Java 库
- 如何构建 Scala 项目
- 如何在 Scala 中执行单元测试
- 如何编写 Scala shell 脚本
- Maps、Sets 和其他集合类
- 面向对象编程
- 函数式编程
- 与并发特性
- 更多的 … 如果您喜欢到目前为止所看到的内容,我们希望您会喜欢本书的其余部分。