深入理解Scala核心规则教程.doc_第1页
深入理解Scala核心规则教程.doc_第2页
深入理解Scala核心规则教程.doc_第3页
深入理解Scala核心规则教程.doc_第4页
深入理解Scala核心规则教程.doc_第5页
全文预览已结束

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Read Eval Print Loop (REPL)REPL在Scala里面指的是直接运行scala.exe进入的交互式命令行模式。广义上讲,也泛指那些在线编程工具。核心规则1:请使用REPL来熟悉Scala语言。Scala的REPL有个好处是能够将我们输入的每行代码的内部表示反馈出来。比如:scala def add(a:Int, b:Int):Int = a + badd: (a: Int, b: Int)Int我们定义一个函数,完成两个数的加法。Scala回显给我们的内容可以帮助我们写代码。表达式与语句表达式与语句的区别是:语句是用来执行的,而表达式是用来求值的。在程序员的世界里,表达式就是返回值,语言就是没有返回值执行程序。Scala是表达式导向的编程语言。但并不是100%成立,Scala代码中还是有控制语块,毕竟我们写程序就是为了控制各种实体为我们服务的。核心规则2:使用表达式,而不是语句。这条规则主要是帮助我们简化代码,就像前面加法的例子,a+b就是一个表达式。相比于我们C语言写的相同实现,简单不好。代码里面,像这样的例子肯定还是存在很多的。不要使用Return当我们使用表达式的时候,就不需要Return了。因为表达式本身就是用来求值的,我们必要再去显式地说我现在要返回什么。Scala编译器自动使用最后一个表达式的返回值作为函数的返回值。我们应该记得一个编程指导意见就是函数在同一个地方返回。如果我们现在没有Return语句了,像在Scala中,有没有类似的编程指导呢?看个例子:object NoReturn extends scala.App def createErrorMessage1(errorCode : Int) : String = val result = errorCode match case 1 = Network Failure case 2 = I/O Failure case 3 = Unknown Error return result def createErrorMessage2(errorCode: Int) : String = var result : String = null / not val errorCode match case 1 = result = Network Failure case 2 = result = I/O Failure case _ = result = Unknown Error return result; def createErrorMessage3(errorCode : Int) : String = errorCode match case 1 = Network Failure case 2 = I/O Failure case 3 = Unknown Error println(createErrorMessage1(1) println(createErrorMessage2(2) println(createErrorMessage3(3) println(1 matchcase 1 = Network Failure case 2 = 3) println(2 matchcase 1 = Network Failure case 2 = 3) createErrorMessage2应该是我们以往的写法。定义一个局部变量,然后匹配errorCode,对其进行赋值。createErrorMessage1是Scala推荐的写法(虽然还不够简洁),它使用的是val而不是var,来声明临时变量。val表示值,赋值后就不允许再更改;var是变量,可以重复赋值。createErrorMessage1的的result之后是一个表达式。求值之后直接就赋值了。createErrorMessage3就更加简洁了,差不多到了终极形态了。函数直接就返回一个表达式,少了临时对象。注:match case支持每个分支返回的类型不同。这个特性在函数式编程中非常有用。Scala虽然支持所有的3中写法,但是推荐最后一种。因为它帮助简化了代码的复杂度,增加了程序的不可变性。不可变指的是程序在执行过程中,所有的状态(变量)都是常量。不可变的代码比可变代码更加容易理解、调试和维护。表达式导向的语言倾向与使用不可变的对象,能减少程序中的可变对象。使用不可变对象核心规则3:使用不可变对象可以大幅减少运行时故障。当面对可变与不可变的选择时,选择不可变对象无疑是最安全的。对象等价性Scala提供了#和=来判断对象是不是等价,它们可以作用于AnyRef(引用)和AnyVal(值)。对象的哈希值和equal应该成对出现。因为等价性经常使用到了hash值。import collection.immutable.HashMap class Point2(var x: Int, var y: Int) extends Equals def move(mx: Int, my: Int) : Unit = x = x + mx y = y + my override def hashCode(): Int = y + (31*x) def canEqual(that: Any): Boolean = that match case p: Point2 = true case _ = false override def equals(that: Any): Boolean = def strictEquals(other: Point2) = this.x = other.x & this.y = other.y that match case a: AnyRef if this eq a = true case p: Point2 = (p canEqual this) & strictEquals(p) case _ = false object ObjecteEquality extends scala.App val x = new Point2(1,1) val y = new Point2(1,2) val z = new Point2(1,1) println(x = y) / false println(x = z) / true val map = HashMap(x - HAI, y - ZOMG) println(map(x) / HAI println(map(y) / ZOMG println(map(z) / HAI, if we remove hashCode, there will be an exception x.move(1,1) / println(map(x) /Exception in thread main java.util.NoSuchElementException: key not found: Point240 println(map.find(_._1 = x) 3-22行定义了一个Point2类,它继承自Equals。trait Equals extends Any def canEqual(that: Any): Boolean def equals(that: Any): Boolean 定义了自己的move方法和hashCode方法。canEqual用来判断是否可以在对象上应用equal方法,这里只是检查是否类型匹配。equal包含一个内部函数strictEquals用来判断对象的成员是否相等。equal首先检查是不是引用了同一个Point2对象,如果是,直接返回true。否则,检查类型是不是匹配,如果是,用strictEquals用来判断对象的成员是否相等。第36行:println(map(z),它的正确执行依赖于hashCode是否定义。Map在寻找指定key的值的时候,会调用key.#。第38行,由于move改变了x的内部状态,hashCode计算出来的新值当做key去Map里面查找,找不到对应的值,就会报NoSuchElementException异常。第40行,比较奇特。看下find的定义:trait IterableLike:override /*TraversableLike*/ def find(p: A = Boolean): OptionA = iterator.find(p) object Iterator:def find(p: A = Boolean): OptionA = var res: OptionA = None while (res.isEmpty & hasNext) val e = next() if (p(e) res = Some(e) res 传给find的是一个predicate。迭代器遍历集合中的每个元素,并将该元素作为参数传给predicate。所有我们这里传给predicate的参数是一个键值对A,B。_就是传给predicate的参数。_1指的是键值对中的第一个元素(实际上是元组中的第一个元素),即A,也就是作为key的Point2。现在很容易明白这句的意思了,就是与x的hashCode一样的元素。_1的定义位于:trait Product2:/* A projection of element 1 of this Product. * return A projection of element 1. */

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论