Scala 学习笔记
// 代码区块控制 val Exit = new Breaks Exit.breakable { for (j <- 'a' to 'e') { if (j == 'c') Exit.break else println(s"j: $j") }
}
// 尾递归标记 @tailrec import scala.annotation.tailrec def factorial(n: Int): Int = { @tailrec def factorialAcc(acc: Int, n: Int): Int = { if (n <= 1) acc else factorialAcc(n * acc, n - 1) } factorialAcc(1, n) }
// 管道方式的匹配模式 val i = 5 i match { case 1 | 3 | 5 | 7 | 9 => println("odd") case 2 | 4 | 6 | 8 | 10 => println("even") } trait Command case object Start extends Command case object Go extends Command case object Stop extends Command case object Whoa extends Command def executeCommand(cmd: Command) = cmd match { case Start | Go => start() case Stop | Whoa => stop() }
// 模式匹配 def echoWhatYouGaveMe(x: Any): String = x match { // constant patterns case 0 => "zero" case true => "true" case "hello" => "you said 'hello'" case Nil => "an empty List" // sequence patterns case List(0, _, _) => "a three-element list with 0 as the first element" case List(1, _*) => "a list beginning with 1, having any number of elements" case Vector(1, _*) => "a vector starting with 1, having any number of elements" // tuples case (a, b) => s"got $a and $b" case (a, b, c) => s"got $a, $b, and $c" // constructor patterns case Person(first, "Alexander") => s"found an Alexander, first name = $first" case Dog("Suka") => "found a dog named Suka" // typed patterns case s: String => s"you gave me this string: $s" case i: Int => s"thanks for the int: $i" case f: Float => s"thanks for the float: $f" case a: Array[Int] => s"an array of int: ${a.mkString(",")}" case as: Array[String] => s"an array of strings: ${as.mkString(",")}" case d: Dog => s"dog: ${d.name}" case list: List[_] => s"thanks for the List: $list" case m: Map[_, _] => m.toString case _ => "Unknown" }
// Sealed class: // 匹配的case class是无法穷举的,Sealed class只能在和他相同的文件中定义子类,所以只需要关注 // 当前文件的case class匹配的列举,并且如果列举不全则编译时有Warning sealed trait RandomThing case class RandomFile(f: File) extends RandomThing case class RandomString(s: String) extends RandomThing class RandomNoiseMaker { def makeRandomNoise(t: RandomThing) = t match { case RandomFile(f) => playSoundFile(f) case RandomString(s) => speak(s) } }
case class Person(firstName: String, lastName: String) object Test2 extends App { def matchType(x: Any): String = x match { //case x: List(1, _*) => s"$x" // doesn't compile case x @ List(1, _*) => s"$x" // works; prints the list //case Some(_) => "got a Some" // works, but can't access the Some //case Some(x) => s"$x" // works, returns "foo" case x @ Some(_) => s"$x" // works, returns "Some(foo)" case p @ Person(first, "Doe") => s"$p" // works, returns "Person(John,Doe)" } println(matchType(List(1,2,3))) // prints "List(1, 2, 3)" println(matchType(Some("foo"))) // prints "Some(foo)" println(matchType(Person("John", "Doe"))) // prints "Person(John,Doe)" }
def toInt(s: String): Option[Int] = { try { Some(Integer.parseInt(s.trim)) } catch { case e: Exception => None } } toInt("42") match { case Some(i) => println(i) case None => println("That wasn't an Int.") }
num match {
case x if x == 1 => println("one, a lonely number")
case x if (x == 2 || x == 3) => println(x)
case _ => println("some other value")
}
// Getter And Setter class Person(private var _name: String) { def name = _name def name_=(aName: String) { _name = aName } }
class Stock { var delayedPrice: Double = _ private var currentPrice: Double = _ } public class Stock extends java.lang.Object implements scala.ScalaObject { public double delayedPrice(); public void delayedPrice_$eq(double); public Stock(); }
面向对象: 继承 class Person(var name: String, var address: Address) { override def toString = if (address == null) name else s"$name @ $address" } class Employee(name: String, var address: Address, var age: Int) extends Person(name, address) case class Address(city: String, state: String) val teresa = new Employee("Teresa", Address("Louisville", "KY"), 25)
// 面向对象: 继承 -> 构造函数 case class Address (city: String, state: String) case class Role (role: String) class Person (var name: String, var address: Address) { // no way for Employee auxiliary constructors to call this constructor def this (name: String) { this(name, null) address = null } override def toString = if (address == null) name else s"$name @ $address" } class Employee (name: String, role: Role, address: Address) extends Person (name, address) { def this (name: String) { this(name, null, null) } def this (name: String, role: Role) { this(name, role, null) } def this (name: String, address: Address) { this(name, null, address) } }
// 抽象类 和 抽象方法 abstract class BaseController(db: Database) { def save { db.save } def update { db.update } def delete { db.delete } // abstract def connect // an abstract method that returns a String def getStatus: String // an abstract method that takes a parameter def setServerName(serverName: String) } abstract class Pet (name: String) { val greeting: String var age: Int def sayHello { println(greeting) } override def toString = s"I say $greeting, and I'm $age" } class Dog (name: String) extends Pet (name) { val greeting = "Woof" var age = 2 } class Cat (name: String) extends Pet (name) { val greeting = "Meow" var age = 5 }
// 属性的继承 abstract class Animal { var greeting = "Hello" var age = 0 override def toString = s"I say $greeting, and I'm $age years old." } class Dog extends Animal { greeting = "Woof" age = 2 }
// name and relation are 'val' by default case class Person(name: String, relation: String)
// 类的equals方法和hashCode方法 class Person (name: String, age: Int) { def canEqual(a: Any) = a.isInstanceOf[Person] override def equals(that: Any): Boolean = { that match { case that: Person => that.canEqual(this) && this.hashCode == that.hashCode case _ => false } } override def hashCode:Int = { val prime = 31 var result = 1 result = prime * result + age; result = prime * result + (if (name == null) 0 else name.hashCode) return result } }
// 继承 class Employee(name: String, age: Int, var role: String) extends Person(name, age) { override def canEqual(a: Any) = a.isInstanceOf[Employee] override def equals(that: Any): Boolean = { that match { case that: Employee => that.canEqual(this) && this.hashCode == that.hashCode case _ => false } } override def hashCode:Int = { val ourHash = if (role == null) 0 else role.hashCode super.hashCode + ourHash } }
class PersonTests extends FunSuite { // these first two instances should be equal val nimoy = new Person("Leonard Nimoy", 82) val nimoy2 = new Person("Leonard Nimoy", 82) val shatner = new Person("William Shatner", 82) val ed = new Person("Ed Chigliak", 20) // all tests pass test("nimoy == nimoy") { assert(nimoy == nimoy) } test("nimoy == nimoy2") { assert(nimoy == nimoy2) } test("nimoy2 == nimoy") { assert(nimoy2 == nimoy) } test("nimoy != shatner") { assert(nimoy != shatner) } test("shatner != nimoy") { assert(shatner != nimoy) } test("nimoy != null") { assert(nimoy != null) } test("nimoy != String") { assert(nimoy != "Leonard Nimoy") } test("nimoy != ed") { assert(nimoy != ed) } }
// 内部类 object ClassInObject extends App { // inner classes are bound to the object val oc1 = new OuterClass val oc2 = new OuterClass val ic1 = new oc1.InnerClass val ic2 = new oc2.InnerClass ic1.x = 10 ic2.x = 20 println(s"ic1.x = ${ic1.x}") println(s"ic2.x = ${ic2.x}") } class OuterClass { class InnerClass { var x = 1 } }