apply方法
当类或对象有一个主要用途时,apply方法为你提供了一个很好的语法糖
scala> class Bar{
def apply() =0
}
scala> val bar = new Bar
scala> bar()
res8:Int = 0
在这里,我们实例化一个对象看起来像是在调用一个方法
单例对象
单例对象用于持有一个类的唯一实例。通常用于工厂模式。
object Timer{
var count = 0;
def currentCount(): Long = {
count += 1
count
}
}
可以这样使用:
scala> Timer.currentCount()
res0: Long = 1
单例对象可以和类具有相同的名称,此时该对象也被称为“伴生对象”,我们通常将伴生对象作为工厂使用。
下面这个例子可以不需要使用“new”来创建一个实例了
class Bar(foo: String)
object Bar{
def apply(foo: String) = new Bar(foo)
}
函数即对象
函数是一些特质的集合。具体来说,具有一个参数的函数是Function1
特质的一个实例。这个特征定义了apply()
语法糖,让你调用一个对象时就像在调用一个函数
scala> object addOne extends Function1[Int,Int]{
def apply(m: Int):Int = m + 1
}
scala> addOne(1)
res2:Int = 2
这个Function特质集合下标从0开始一直到22。
为什么是22?主观魔幻数字,我们从来没啥用过超过22个参数的函数
apply语法糖有助于统一对象和函数式编程的二重性。你可以传递类,并把它们当做函数使用,而函数本质上是类的实例。
在类中独立定义的方法是方法不是函数,而在repl中独立定义的方法是Function*实例
可以使用更快捷的方法代替extends Function[Int,Int]
class AddOne extends(Int => Int){
def apply(m: Int):Int = m + 1
}
包
可以将代码组织在包里
package com.twitter.example
在文件头部定义包,会将文件中所有的代码声明在那个包中。
值和函数不能在类或单例对象之外定义。单例对象是组织静态函数(static function)的有效工具。
scala的设计者是把对象作为Scala的模块系统的一部分进行设计的
模式匹配
匹配值
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"
}
匹配类型
可以使用match来分别处理不同类型的值
def bigger(o: Any):Any = {
o match {
case i: Int if i<0 => i-1
case i: Int => i+1
case d:Double if d<0 => d-0.1
case d:Double => d + 0.1
case text: String => text + "s"
}
}
匹配类成员
def calcType(calc: Calculator) = calc match {
case _ if calc.brand == "HP" && calc.model == "20B" => "financial"
case _ if calc.brand == "HP" && calc.model == "48G" => "scientific"
case _ if calc.brand == "HP" && calc.model == "30B" => "business"
case _ => "unknown"
}
样本类 Case Classes
使用样本类可以方便得存储和匹配类的内容,你不用new关键字就可以创建它们
scala> case class Calculator(brand: String,model: String)
scala> val hp20b = Calculator("HP","20b")
样本类基于构造函数的参数,自动地实现了相等性和易读的toString方法
样本类也可以像普通类那样拥有方法。
样本类就是被设计用在模式匹配中的。
val hp20b = Calculator("HP","20B")
val hp30b = Calculator("HP","30B")
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)
}
异常
Scala中的异常可以再try-catch-finally语法中通过模式匹配使用
try也是面向表达式的