Scala 速查表

Scala 速查表

语言

感谢 Brendan O’Connor,此速查表旨在快速参考 Scala 语法结构。由 Brendan O’Connor 根据 CC-BY-SA 3.0 许可证授权。

变量
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

此页面的贡献者