scala School笔记

特质和抽象类怎么选择

  1. 优先使用特质。一个类扩展多个特质是很方便的,但却只能扩展一个抽象类。
  2. 如果你需要构造函数参数,使用抽象类。因为抽象类可以定义带参数的构造函数,而特质不行。例如,你不能说trait t(i: Int) {},参数i是非法的。

类型

一个使用泛型键和值的缓存的例子
trait Cache[K, V] {
  def get(key: K): V
  def put(key: K, value: V)
  def delete(key: K)
}

apply方法

当类或者对象有一个主要用途时,apply方法提供了一个很好的语法糖,可以让实例化对象看起来像是在调用一个方法

scala> FooMaker
res5: FooMaker.type = FooMaker$@27305e6

scala> object FooMaker {
  def apply() = ()=>println("1")}
     | defined object FooMaker

scala> FooMaker
res6: FooMaker.type = FooMaker$@ce5a68e

scala> FooMaker()
res7: () => Unit = 

单例对象

单例对象用于持有一个类的唯一实例。通常用于工厂模式

object Timer {
  var count = 0

  def currentCount(): Long = {
    count += 1
    count
  }
}
scala> Timer.currentCount()
res0: Long = 1

模式匹配

  1. 匹配值
val times = 1

times match {
  case 1 => "one"
  case 2 => "two"
  case _ => "some other number"
}

使用守卫进行匹配
times match {
  case i if i == 1 => "one"
  case i if i == 2 => "two"
  case _ => "some other number"
}
  1. 匹配类型
def bigger(x:Any):Any={
  x match {
    case i:Int if i<0 => i-1
    case i:Int if i>=0 => i+1
    case d:Double if d<0.0 => d
    case text:String => text
    case _ => "fuck"
  }
}
  1. 匹配样本类成员
    使用样本类可以方便得存储和匹配类的内容。你不用new关键字就可以创建它们。
case class Calculator(brand: String, model: String)

def calcType(calc: Calculator) = calc match {
  case Calculator("HP", "20B") => "financial"
  case Calculator("HP", "48G") => "scientific"
  case Calculator("HP", "30B") => "business"
  case Calculator(ourBrand, ourModel) => "Calculator: %s %s is of unknown type".format(ourBrand, ourModel)
case Calculator(_, _) => "Calculator of unknown type"//与上句相同
}

变性 Variance

Scala的类型系统必须同时解释类层次和多态性

  1. 协变
scala> class Covariant[+A]
defined class Covariant

scala> val cv: Covariant[AnyRef] = new Covariant[String]
cv: Covariant[AnyRef] = Covariant@4035acf6

2.逆变

scala> class Contravariant[-A]
defined class Contravariant

scala> val cv: Contravariant[String] = new Contravariant[AnyRef]
cv: Contravariant[AnyRef] = Contravariant@49fa7ba

协变、逆变都是对应泛型参数,之前把泛型参数和函数参数搞混了。可以把协变逆变理解为一个壳子里套的某个参数支持协变逆变

class Animal { val sound = "rustle" }
class Bird extends Animal { override val sound = "call" }
class Chicken extends Bird { override val sound = "cluck" }

class Test[-R]{
  def sum(a:Test[Bird]) ="wuxiang"
val a = new Test
a.sum(new Test[Bird])
res24: String = wuxiang
a.sum(new Test[Animal])
res25: String = wuxiang

你可能感兴趣的:(scala School笔记)