1、标示符:Scala中可以使用Unicode字符组成标示符,还可以使用所有的AscII字符,但是建议使用类似于java标示符的方式。
2、中置操作符:a 标识符b。如 1-2,1 to 10 其实都是方法调用。中置操作符可以用来重写操作符,重写操作符只需要在类中定义该操作符的方法。
3、一元操作符:a 标识符,等同于a.标识符()。一元操作符比较特殊的四个操作符:+、-、!、~可以作为前置操作符。赋值操作符:a+=b。
4、scala当中大部分操作符都是左结合的,除了以冒号(:)结尾的操作符合赋值操作符。如用于构造列表的::操作符就是右结合的:
val a=List(1,2,3,4)
val b=-1::0::a//实际上是按照这样的顺序-1::(2::a)。实际上右结合就是调用第二个参数的方法:a.::(0).::(-1)
5、类似于apply方法的update方法:表达形式:obj(arg1,arg2,..)=value,对应于调用obj.update(arg1,arg2,…,value)方法。apply方法常用于伴生对象中用来构造对象而不显示的使用new,而update方法常被用于数组和映射中改值使用。
6、apply方法的反向操作方法unapply,常用在对象中用于生成对象,但他的输入是一个对象然后通过这个对象构造对象:val author="wang he ping" val Name(first,last)=author.这里就是掉用了Name.unapply(author)来构造对象。一般unapply方法返回的是Option类型。
1、集合都继承于iterable,与java不同映射也属于同一层继承关系。indexedSeq是数组的超类型。
2、Scala中有可变和不可变的集合,不可变的集合不可以改变但是可以通过操作生成新的不可变集合。
3、不可变序列:vector类似于数组但底层机构是树,不是线性的不过也支持快速的随机访问, Range表示的是一个整数序列,Range对象只存储起始值,结束值和增值。可变序列与java中的大体类似
4、列表:在Scala中列表要么是空的要么是一个head元素加上一个tail元素而tail元素又是一个链表,我的思路是:嵌套链表,以head开始tail嵌套。存在链表操作符::用于将两个链表合成新的链表如:9::List(4,2) 结果是List(9,4,2),head为9.在遍历时可以用迭代器进行遍历也可以直接通过递归。
5、可变列表与不可变列表类似,只是可以通过elem和next对头部和尾部进行修改。如 var cur=list cur.elem=0,cur.next=list2
6、用于添加或去除元素的操作符总结如下:
7、将函数应用于集合:集合中有一个map方法接收一元函数为参数然后对集合中所有元素进行处理。还存在接收二元函数为输入参数的方法如:reduceLeft,foldLeft等。
8、拉链操作:zip 用于将两个集合进行结合成一个集合,而且新生成的集合长度与两个集合中短的相同。zipwthIndex用于将集合和索引进行结合。
9、流式一个尾部被懒计算的不可变列表,只有当需要时才会计算。流操作符是#:。流的性质当你不用时流只计算了头元素,其他元素采用懒计算,只有用到时才计算。如下:
//采用#:生成流
def numsFrom(n:BigInt):Stream[BigInt]=n#::numsFrom(n+1);
def main(args: Array[String]): Unit = {
val squares=numsFrom(1).map(x=>x*x)//懒计算
println(squares)//这里只输出Stream(1,?)
print(squares.take(5).force)//这里强制计算输出:Stream(1, 4, 9, 16, 25)
}
10、Scala中的集合可以与java中的集合进行互操作,同样也有线程安装的集合但不建议使用。
11、并行集合,Scala中提供了方便对大型集合方便的并行操作来加快速度,感觉有点类似于MapReduce。通过par方法产出当前集合的一个并行实现。如: for(i<-(0 until 100).par)print(i+" ")将不会按大小正常输出,由于底层用了多个线程进行并发计算。但是对于求和等操作会将多个线程的结果进行叠加: print(((0 until 101).toList).par.sum)将输出5050
第十四章模式匹配和样例类
1、Scala中的switch通过 ch match{ case 条件 => 语句},每个case后不需要break,存在与default想类似的全匹配:_ 。另外可以加条件进行判断来进行处理以匹配更多。如:case _ if(Character.isDigit(ch))=> 语句。
2、模式中的变量:在case关键字后面可以跟着一个变量名,那么匹配的表达式会赋值给那个变量,其实全部匹配就是一个变量只是变量名为。同样你也可以在守卫中使用变量。如case i if character.isDigit(i)=>语句。
3、Scala中你也可以对表达式的类型进行匹配,如:但是不能匹配特定的泛型,如特定的Map类型
obj match {
case x:Int=>x //其中x为变量,只能匹配整数并将obj赋值给x
case s:String=>Integer.parseInt(s)//与x类似,只是此处为字符串
case _:BigInt=>Int.Maxvalue//变量名为_,只能匹配obj为BigInt的类型
case _ =>0//全部匹配
}
4、匹配数组、列表和元组:匹配时可以通过数组的个数,列表的头尾,元组的组成等进行匹配。
5、样例类是一种特殊的类,经常被用于模式匹配,样例类的创建方式很简单如下:
abstract class Amout
case class Dollar(value:Double) extends Amount//继承于Amount
case object Nothind extends Amout//单例也可以样例类
其中构造器中的每一个参数都为val(除非显示定义为var),在伴生对象中提供apply方法用于构造新对象,提供unapply方法让模式匹配可以工作。并且将生成toSting,equals,hashcode,copy等方法。这些都是在定义该样例类时自动生成的。
在模式匹配时可以将类型为Amount的对象和样例类进行匹配,然后参数会直接绑定然后直接用样例类中的变量如下:
amout math{
case Dollar(v)=>"$"+v
case Nothing =>" "
}
6、Option类型:Scala中Option[T]类型是用来处理java中null值类型的,Option有两个子类型一个为None,一个位Some[T]。比如map的get方法在java中可能返回为null而导致出现NullPointerException异常,而Scala中返回的是一个Option[T]类型当值不存在时为None,存在时返回Some(T)通过get方法可以获得map中的值。
7、偏函数:被包在花括号没的一组case是一个偏函数,一个并非对所有输入都有定义的函数,偏函数是PartialFunction[A,B]的一个实例,其中A为输入,B为返回类型。该类有两个方法,apply方法用于模式匹配,一个isDefinedAt从输入中匹配到则返回True。如下:
val f:PartialFunction[Chart,Int]={case '+' => 1;case '-' => -1}
f('+')//调用f.apply('+'),返回1
f.isDefinedAt('-')//返回true
f('0')//抛出MatchError
import scala.actors.Actor
class HiActor extends Actor{
def act(){
while(true){
receive{
case "Hi" =>println("Hello")
}
}
}
}
//启动actor
val actor1=new HiActor
actor1.start()
其中act方法类似于java中的run方法。不同于java中的并发,Actor是针对消息进行活动的。其中的receive就是用于接收消息的。
2、发送消息:actor是一个处理异步消息的对象,你可以向某个actor发送消息,actor可以对该消息进行处理也可以向下传递给其他actor。发送消息的方式很简单如:常用样例类(case class className(参数))作为消息对象。