密封类
特质(trait)和类(class)可以用sealed标记为密封的,这意味着其所有子类都必须与之定义在相同文件中。
sealed abstract class Furniture case class Couch() extends Furniture case class Chair() extends Furniture def findPlaceToSit(piece: Furniture): String = piece match { case a: Couch => "Lie on the couch" case b: Chair => "Sit on the chair" }
单例对象
单例对象是一种特殊的类,可以使用关键字object来表示。单例对象是延时创建的,只有当他被第一次使用的时候才会创建。
package logging object Logger { def info(message: String): Unit = println(s"INFO: $message") }
单例对象的一个作用就是定义功能性方法,可以在任何地方被使用,如上例中的info方法。可以像如下的方式使用:
import logging.Logger.info class Project(name: String, daysToComplete: Int) class Test { val project1 = new Project("TPS Reports", 1) val project2 = new Project("Website redesign", 5) info("Created projects") // Prints "INFO: Created projects" }
伴生对象
伴生对象是指与某个类名相同的单例对象,类和它的伴生对象可以互相访问其私有成员。下面是一个伴生对象的例子:
import scala.math._ case class Circle(radius: Double) { import Circle._ def area: Double = calculateArea(radius) } object Circle { private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0) } val circle1 = Circle(5.0) circle1.area
伴生对象circle1可以访问类中定义的area.
注意:类和它的伴生对象必须定义在同一个源文件里。
正则表达式模式
在Scala中,可以使用.r方法将任意字符串变成一个正则表达式。如下所示:
import scala.util.matching.Regex val numberPattern: Regex = "[0-9]".r numberPattern.findFirstMatchIn("awesomepassword") match { case Some(_) => println("Password OK") case None => println("Password must contain a number") }
你还可以使用括号来同时匹配多组正则表达式。
import scala.util.matching.Regex val keyValPattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r val input: String = """background-color: #A03300; |background-image: url(img/header100.png); |background-position: top center; |background-repeat: repeat-x; |background-size: 2160px 108px; |margin: 0; |height: 108px; |width: 100%;""".stripMargin for (patternMatch <- keyValPattern.findAllMatchIn(input)) println(s"key: ${patternMatch.group(1)} value: ${patternMatch.group(2)}")
For表达式
在Scala中for循环是和yield一起使用的,他的形式是for (enumerators) yield e。 此处 enumerators 指一组以分号分隔的枚举器。这里的enumerator 要么是一个产生新变量的生成器,要么是一个过滤器。for 表达式在枚举器产生的每一次绑定中都会计算 e 值,并在循环结束后返回这些值组成的序列。 如下所示:
case class User(name: String, age: Int) val userBase = List(User("Travis", 28), User("Kelly", 33), User("Jennifer", 44), User("Dennis", 23)) val twentySomethings = for (user <- userBase if (user.age >=20 && user.age < 30)) yield user.name // i.e. add this to a list twentySomethings.foreach(name => println(name)) // prints Travis Dennis
下面是一个更加复杂的例子:
def foo(n: Int, v: Int) = for (i <- 0 until n; j <- i until n if i + j == v) yield (i, j) foo(10, 10) foreach { case (i, j) => println(s"($i, $j) ") // prints (1, 9) (2, 8) (3, 7) (4, 6) (5, 5) }