变量 |
|
var x = 5
好
x = 6
|
变量。 |
val x = 5
差
x = 6
|
常量。 |
var x: Double = 5
|
显式类型。 |
函数 |
|
好 def f(x: Int) = { x * x }
差 def f(x: Int) { x * x }
|
定义函数。 隐藏错误:如果没有 = ,则它是一个返回 Unit 的过程;会造成严重后果。 已弃用 Scala 2.13。 |
好 def f(x: Any) = println(x)
差 def f(x) = println(x)
|
定义函数。 语法错误:需要为每个参数指定类型。 |
type R = Double
|
类型别名。 |
def f(x: R) 与 def f(x: => R)
|
按值调用。
按名称调用(惰性参数)。 |
(x: R) => x * x
|
匿名函数。 |
(1 to 5).map(_ * 2) 与 (1 to 5).reduceLeft(_ + _)
|
匿名函数:下划线是按位置匹配的参数。 |
(1 to 5).map(x => x * x)
|
匿名函数:要使用参数两次,必须为其命名。 |
(1 to 5).map { x =>
val y = x * 2
println(y)
y
}
|
匿名函数:块样式返回最后一个表达式。 |
(1 to 5) filter {
_ % 2 == 0
} map {
_ * 2
}
|
匿名函数:管道样式(或括号)。 |
def compose(g: R => R, h: R => R) =
(x: R) => g(h(x)) val f = compose(_ * 2, _ - 1)
|
匿名函数:要传入多个块,需要外部括号。 |
val zscore =
(mean: R, sd: R) =>
(x: R) =>
(x - mean) / sd
|
柯里化,明显的语法。 |
def zscore(mean: R, sd: R) =
(x: R) =>
(x - mean) / sd
|
柯里化,明显的语法。 |
def zscore(mean: R, sd: R)(x: R) =
(x - mean) / sd
|
柯里化,语法糖。但是 |
val normer =
zscore(7, 0.4) _
|
需要尾随下划线才能获得部分,仅适用于语法糖版本。 |
def mapmake[T](g: T => T)(seq: List[T]) =
seq.map(g)
|
泛型类型。 |
5.+(3); 5 + 3 (1 to 5) map (_ * 2)
|
中缀语法糖。 |
def sum(args: Int*) =
args.reduceLeft(_+_)
|
可变参数。 |
包 |
|
import scala.collection._
|
通配符导入。 |
import scala.collection.Vector import scala.collection.{Vector, Sequence}
|
选择性导入。 |
import scala.collection.{Vector => Vec28}
|
重命名导入。 |
import java.util.{Date => _, _}
|
从 java.util 导入所有内容,但 Date 除外。 |
在文件开头 package pkg
按范围打包 package pkg {
...
}
包单例 package object pkg {
...
}
|
声明一个包。 |
数据结构 |
|
(1, 2, 3)
|
元组文字 (Tuple3 )。 |
var (x, y, z) = (1, 2, 3)
|
解构绑定:通过模式匹配进行元组拆包。 |
差
var x, y, z = (1, 2, 3)
|
隐藏错误:每个都分配给整个元组。 |
var xs = List(1, 2, 3)
|
列表(不可变)。 |
xs(2)
|
括号索引 (幻灯片)。 |
1 :: List(2, 3)
|
Cons。 |
1 to 5 与 1 until 6 1 to 10 by 2
|
范围糖相同。 |
()
|
空括号是 Unit 类型的单例值。 相当于 C 和 Java 中的 void 。 |
控制结构 |
|
if (check) happy else sad
|
条件。 |
if (check) happy
与
if (check) happy else ()
|
条件糖。 |
while (x < 5) {
println(x)
x += 1
}
|
While 循环。 |
do {
println(x)
x += 1
} while (x < 5)
|
Do-while 循环。 |
import scala.util.control.Breaks._
breakable {
for (x <- xs) {
if (Math.random < 0.1)
break
}
}
|
Break (幻灯片)。 |
for (x <- xs if x % 2 == 0)
yield x * 10
与
xs.filter(_ % 2 == 0).map(_ * 10)
|
For-comprehension:过滤/映射。 |
for ((x, y) <- xs zip ys)
yield x * y
与
(xs zip ys) map {
case (x, y) => x * y
}
|
For-comprehension:解构绑定。 |
for (x <- xs; y <- ys)
yield x * y
与
xs flatMap { x =>
ys map { y =>
x * y
}
}
|
For-comprehension:笛卡尔积。 |
for (x <- xs; y <- ys) {
val div = x / y.toFloat
println("%d/%d = %.1f".format(x, y, div))
}
|
For-comprehension:命令式。
sprintf 样式. |
for (i <- 1 to 5) {
println(i)
}
|
For-comprehension:迭代包括上限。 |
for (i <- 1 until 5) {
println(i)
}
|
For-comprehension:迭代省略上限。 |
模式匹配 |
|
好 (xs zip ys) map {
case (x, y) => x * y
}
差 (xs zip ys) map {
(x, y) => x * y
}
|
在函数参数中使用模式匹配。 |
差
val v42 = 42
3 match {
case v42 => println("42")
case _ => println("Not 42")
}
|
v42 被解释为匹配任何 Int 值的名称,并打印“42”。 |
好
val v42 = 42
3 match {
case `v42` => println("42")
case _ => println("Not 42")
}
|
带有反引号的 `v42` 被解释为现有的 val v42 ,并打印“Not 42”。 |
好
val UppercaseVal = 42
3 match {
case UppercaseVal => println("42")
case _ => println("Not 42")
}
|
UppercaseVal 被视为现有 val,而不是新模式变量,因为它以大写字母开头。因此,检查 UppercaseVal 中包含的值是否等于 3 ,并打印“Not 42”。 |
面向对象 |
|
class C(x: R)
|
构造函数参数 - x 仅在类主体中可用。 |
class C(val x: R)
var c = new C(4)
c.x
|
构造函数参数 - 自动定义公共成员。 |
class C(var x: R) {
assert(x > 0, "positive please")
var y = x
val readonly = 5
private var secret = 1
def this() = this(42)
}
|
构造函数是类主体。 声明公共成员。 声明可获取但不可设置的成员。 声明私有成员。 备用构造函数。 |
new {
...
}
|
匿名类。 |
abstract class D { ... }
|
定义抽象类(不可创建)。 |
class C extends D { ... }
|
定义继承类。 |
class D(var x: R)
class C(x: R) extends D(x)
|
继承和构造函数参数(愿望清单:默认情况下自动传递参数)。 |
object O extends D { ... }
|
定义单例(类似模块)。 |
trait T { ... }
class C extends T { ... }
class C extends D with T { ... }
|
特征。 带有实现的接口。无构造函数参数。 可混合。 |
trait T1; trait T2
class C extends T1 with T2
class C extends D with T1 with T2
|
多个特征。 |
class C extends D { override def f = ...}
|
必须声明方法覆盖。 |
new java.io.File("f")
|
创建对象。 |
差 new List[Int]
好 List(1, 2, 3)
|
类型错误:抽象类型。 相反,约定:可调用的工厂掩盖类型。 |
classOf[String]
|
类文字。 |
x.isInstanceOf[String]
|
类型检查(运行时)。 |
x.asInstanceOf[String]
|
类型转换(运行时)。 |
x: String
|
归属(编译时间)。 |
|
选项 |
|
Some(42)
|
构造一个非空可选值。 |
None
|
单例空可选值。 |
Option(null) == None
Option(obj.unsafeMethod)
但是
Some(null) != None
|
空安全可选值工厂。 |
val optStr: Option[String] = None
与
val optStr = Option.empty[String]
|
空可选值的显式类型。 空可选值的工厂。 |
val name: Option[String] =
request.getParameter("name")
val upper = name.map {
_.trim
} filter {
_.length != 0
} map {
_.toUpperCase
}
println(upper.getOrElse(""))
|
管道样式。 |
val upper = for {
name <- request.getParameter("name")
trimmed <- Some(name.trim)
if trimmed.length != 0
upper <- Some(trimmed.toUpperCase)
} yield upper
println(upper.getOrElse(""))
|
For-comprehension 语法。 |
option.map(f(_))
与
option match {
case Some(x) => Some(f(x))
case None => None
}
|
在可选值上应用一个函数。 |
option.flatMap(f(_))
与
option match {
case Some(x) => f(x)
case None => None
}
|
与 map 相同,但函数必须返回一个可选值。 |
optionOfOption.flatten
与
optionOfOption match {
case Some(Some(x)) => Some(x)
case _ => None
}
|
提取嵌套选项。 |
option.foreach(f(_))
与
option match {
case Some(x) => f(x)
case None => ()
}
|
在可选值上应用一个过程。 |
option.fold(y)(f(_))
与
option match {
case Some(x) => f(x)
case None => y
}
|
在可选值上应用函数,如果为空则返回默认值。 |
option.collect {
case x => ...
}
与
option match {
case Some(x) if f.isDefinedAt(x) => ...
case Some(_) => None
case None => None
}
|
在可选值上应用部分模式匹配。 |
option.isDefined
与
option match {
case Some(_) => true
case None => false
}
|
如果不为空,则为true 。 |
option.isEmpty
与
option match {
case Some(_) => false
case None => true
}
|
如果为空,则为true 。 |
option.nonEmpty
与
option match {
case Some(_) => true
case None => false
}
|
如果不为空,则为true 。 |
option.size
与
option match {
case Some(_) => 1
case None => 0
}
|
如果为空,则为0 ,否则为1 。 |
option.orElse(Some(y))
与
option match {
case Some(x) => Some(x)
case None => Some(y)
}
|
如果为空,则求值并返回备用可选值。 |
option.getOrElse(y)
与
option match {
case Some(x) => x
case None => y
}
|
如果为空,则求值并返回默认值。 |
option.get
与
option match {
case Some(x) => x
case None => throw new Exception
}
|
返回一个值,如果为空则抛出异常。 |
option.orNull
与
option match {
case Some(x) => x
case None => null
}
|
返回一个值,如果为空则为null 。 |
option.filter(f)
与
option match {
case Some(x) if f(x) => Some(x)
case _ => None
}
|
可选值满足谓词。 |
option.filterNot(f(_))
与
option match {
case Some(x) if !f(x) => Some(x)
case _ => None
}
|
可选值不满足谓词。 |
option.exists(f(_))
与
option match {
case Some(x) if f(x) => true
case Some(_) => false
case None => false
}
|
在可选值上应用谓词,如果为空则为false 。 |
option.forall(f(_))
与
option match {
case Some(x) if f(x) => true
case Some(_) => false
case None => true
}
|
在可选值上应用谓词,如果为空则为true 。 |
option.contains(y)
与
option match {
case Some(x) => x == y
case None => false
}
|
检查值是否等于可选值,如果为空则为false 。 |