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 }
}

 

posted @ 2014-02-18 10:33  rilley  阅读(314)  评论(0编辑  收藏  举报