scala快速学习笔记(二):控制结构,类和对象
IV.控制结构
1.if/else
除基本用法外,if/else语句能用来赋值,进而代替?:
运算符。这得益于在Scala中,每个语句块都有值,就是该语句块最后一个语句的值。请看下面的代码。
def abs(x: Int) = if(x < 0) -x else x
2.与If语句不同,While语句本身没有值,即整个While语句的结果是Unit类型的()。
PS:scala中赋值语句也没有值。
3.用于迭代一个集合的for语句,格式为for(item <- collection)。一些collection举例:
0 to list.length - 1
0 until list.length
val list = List("Tom", "Jach", "Jimmy", "Abby")
嵌套for循环 直接分号隔开就行。
for(i <- 0 to 1; j <- 1 to 2; k <- 2 to 3) {
println("i = %d, j = %d, k = %d".format(i, j, k))
}
- 条件for循环 例如下面代码,i带有条件
i % 2 == 0
,这意味着,仅有满足这个条件的i才会被循环执行。
for{i <- 0 to 5
if i % 2 == 0
j <- 1 to 2} {
println("i = %d, j = %d".format(i, j))
}
- 中途绑定变量
//引入了变量lower,这与通常我们定义变量的方式相比,只是少了val。这个变量在for表达式中和循环体中都可以使用。
val list = List("Html", "XML", "JSON", "text", "md")
for{ ext <- list
lower = ext.toLowerCase
if lower != "html"} {
println("Accepted data format: " + lower)
}
产生新的集合 for(claus) yield {body} 可以用来产生新的集合。
val result =
for(i <- 1 to 3; j <- 2 to 4)
yield {
i + j
}
println(result)
4.match
"your selector" match {
case "case 1" => //handle case 1
case "case 2" => //handle case 2
...
case _ => //handle the rest, like default in switch-case
}
- 任意类型的常量或结果为常量的表达式都可以用于match语句。
- 每个分支不需要以break结束,因为Scala里没有贯穿执行(fall through)。
- 与if表达式一样,match表达式也有结果。这也是可以理解的,match其实是多个分支的if的另一种写法。
def passed_?(grade: Char) = {
grade match {
case 'A' | 'B' | 'C' => true //case 'A' | 'B' | 'C' => true
这正是其他语言中,switch-case贯穿执行的情况
case _ => false
}
}
5.异常
当碰到异常情况时,方法抛出一个异常,终止方法本身的执行,异常传递到其调用者,调用者可以处理该异常,也可以升级到它的调用者。运行系统会一直这样升级异常,直到有调用者能处理它。 如果一直没有处理,则终止整个程序。
- 抛出异常:用throw关键字,抛出一个异常对象。所有异常都是Throwable的子类型。throw表达式是有类型的,就是Nothing,因为Nothing是所有类型的子类型,所以throw表达式可以用在需要类型的地方。
//并不像Java代码那样,需要声明方法会抛出异常,这给程序员省去理论很多烦恼。
def divide(x: Int, y: Int): Int = {
if (y == 0) throw new Exception("Divide by zero")
else x / y
}- 捕捉异常:
- 在Scala里,借用了模式匹配的思想来做异常的匹配,因此,在catch的代码里,是一系列case字句。
- 异常捕捉的机制与其他语言中一样,如果有异常发生,catch字句是按次序捕捉的。因此,在catch字句中,越具体的异常越要靠前,越普遍的异常越靠后。 如果抛出的异常不在catch字句中,该异常则无法处理,会被升级到调用者处。
finally字句用于执行不管是正常处理还是有异常发生时都需要执行的步骤,一般用于对象的清理工作。
6.中断循环:
- Scala中没有break或continue关键字。可以使用Breaks类的break方法,来实现退出循环的功能。breakException是一个ControlThrowable类型的异常。此外,你的循环代码还需要用breakable包围起来,breakable的作用是捕获break抛出的异常,以免影响你真正的产品代码。
import scala.util.control.Breaks._
- 函数式编程的思想,尽量避免使用break。函数式编程几乎离不开递归。 更特别的,以下hasHtml是一个尾递归,大部分函数式语言编译器都对尾递归有优化,Scala也不例外。对程序员来说,不用担心使用尾递归会带来性能下降。
val list = List("functions.md", "menu.json", "index.html", "data.xml") def hasHtml(input: List[String]): Boolean = {
input match {
case Nil => false
case x :: sub => {
if(x.endsWith("html")) return true
else hasHtml(sub)
}
}
} if(hasHtml(list)) println("There is at least one html file in the list")
else println("There is no html file in the list")
V.类和对象
1.默认的访问修饰符是public。
Scala的类都有默认的基本构造函数,可以使用new来创建对象。
在类定义中,所有不属于方法和字段的语句,都属于主构造函数。
基本构造函数的参数就是类参数,类参数(或默认构造函数参数)默认的访问级别是对象私有,即private[this] val,若想要在类外部也能使用,只需显示注明为val或var,比如
class ScoreCalculator(val athlete: String)
。- 私有构造函数 private放在类参数列表前
class ScoreCalculator private(val athlete: String)
class ScoreCalculator(athlete: String) {
private var total, count = 0 println("This is in the primary constructor") def report(score: Int) {
total += score
count += 1
} def score = if (count == 0) 0 else total / count override def toString() = athlete + "'s score is " + score
} val sc = new ScoreCalculator("Yao")
println("\nJust created an object, now you can use it.\n")
sc.report(80)
sc.report(90)
println(sc)
- 辅助构造函数 :构造函数用this标识。必须先调用主构造函数,或者在它之前定义的其他构造函数。这意味着,主构造函数是唯一创建对象的途径,不论你调用的是哪个构造函数。
class ScoreCalculator {
var athlete = ""
var degreeOfDifficulty = 0.0 def this(athlete: String) {
this() //Call primary constructor
this.athlete = athlete
} def this(athlete: String, degreeOfDifficulty: Double) {
this(athlete) //Call another auxiliary constructor
this.degreeOfDifficulty = degreeOfDifficulty
} override def toString = "Athlete: " + athlete + ", degree of difficulty: " + degreeOfDifficulty
} val sc1 = new ScoreCalculator("Gao Min")
sc1.degreeOfDifficulty = 3.7
println(sc1) val sc2 = new ScoreCalculator("Fu Mingxia", 3.5)
println(sc2)
2.类的属性
- scala的getter方法格式如
name_= (parameters)
,名称,下划线和等号是一个整体,之间不能有空格。 - setter方法必须与getter成对出现,也就是不能只写不读。相反,getter可以单独出现,也就是说只读是可能的。
- 没有声明为private的字段自动生成getter,setter方法。
不是很懂,再研究吧。
3.单例对象:消除静态。单例对象可分为两种,不与某个类共享源文件和名称的,称为独立对象(Standalone Object),与此相反,与某个类共享名称的,称为伴生对象(Companion Object)。
- 独立对象类似于静态类,在一个运行环境中,只会有唯一一个这个类型的对象,它是单例设计模式的天然实现,在第一次被使用的时候由运行环境将它实例化。其定义方式与类相似,只是将关键字换成object。 其他的方面也跟类相似,比如可以继承其他类和特质。只是有一个区别,不能有类参数,也就是构造函数参数。
- 如果一个单例对象跟类有相同的名字,而且它们在同一个源文件里,那么就称之为这个类的伴生对象。它和伴生类能互相访问对方的私有成员。
- apply方法是对象的一类特有方法,一般可用于创建伴生类。apply方法可以用简洁的方式调用,形如
Object(args..)。
4.独立对象可以包含main方法,并且可以用extends App表示(app特质)。
object MyApplication extends App {
args.foreach(println)
}
scala快速学习笔记(二):控制结构,类和对象的更多相关文章
- python cookbook第三版学习笔记十:类和对象(一)
类和对象: 我们经常会对打印一个对象来得到对象的某些信息. class pair: def __init__(self,x,y): self.x=x self. ...
- [C#] 类型学习笔记二:详解对象之间的比较
继上一篇对象类型后,这里我们一起探讨相等的判定. 相等判断有关的4个方法 CLR中,和相等有关系的方法有这么4种: (1) 最常见的 == 运算符 (2) Object的静态方法ReferenceEq ...
- [javase学习笔记]-6.2 类与对象的关系
这一节我们来看一下类与对象之间的关系. 我们学习java语言,目的就是用java语言对现实生活中的事物进行描写叙述.那么我们如何来描写叙述呢.这就引出了类,我们在实际实现时,是通过类的形式来体现的. ...
- php笔记(二)PHP类和对象之Static静态关键字
PHP类和对象之Static静态关键字 静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用.静态属性不允许对象使用->操作符调用. class Car { pr ...
- scala快速学习笔记(三):Collections,包
VI.Collections 1.Array 一些常用方法:println, map( _ * 2), filter(_ % 2 == 0), sum, reserve Array是不可变的, ...
- scala快速学习笔记(一):变量函数,操作符,基本类型
为了用spark,先学下scala. 参考教程:http://meetfp.com/zh/scala-basic doc查询:http://docs.scala-lang.org 其它资料:http: ...
- 转:C#制作ORM映射学习笔记二 配置类及Sql语句生成类
在正式开始实现ORM之前还有一点准备工作需要完成,第一是实现一个配置类,这个很简单的就是通过静态变量来保存数据库的一些连接信息,等同于.net项目中的web.config的功能:第二需要设计实现一个s ...
- python cookbook第三版学习笔记十一:类和对象(二)调用父类的方法
在子类中调用父类的方法,可以下面的A.spam(self)的方法. class A(object): def spam(self): print 'A.spam' class ...
- python cookbook第三版学习笔记十三:类和对象(三)描述器
__get__以及__set__:假设T是一个类,t是他的实例,d是它的一个描述器属性.读取属性的时候T.d返回的是d.__get__(None,T),t.d返回的是d.__get__(t,T).说法 ...
随机推荐
- python3--命名空间字典
命名空间字典 我们学到了模块的命名空间实际上是以字典的形式实现的,并且可以由内置属性__dict__显示这一点.类和实例对象也是如此:属性点号运算其实内部就是字典的索引运算,而属性继承其实就是搜索连结 ...
- 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 1) Problem K Tournament Wins
Problem K — limit 1 second Tournament Wins 这个题就是有2^n队伍,他现在的实力水平是第k位,采用的是淘汰制 问一下你他的胜场数的期望 这人能 win> ...
- 【bzoj4383】[POI2015]Pustynia 线段树优化建图+差分约束系统+拓扑排序
题目描述 给定一个长度为n的正整数序列a,每个数都在1到10^9范围内,告诉你其中s个数,并给出m条信息,每条信息包含三个数l,r,k以及接下来k个正整数,表示a[l],a[l+1],...,a[r- ...
- jenkins换端口号
两个地方 1,检查 /etc/init.d/jenkins 脚本,修改 do_start 函数的 check_tcp_port 命令,端口号从 8080 换成 8082: 2,修改 /etc/defa ...
- 【Hihocoder1034】毁灭者问题(splay,树状数组)
题意: 假设你拥有 n 个魔法单位,他们从左到有站在一行,编号从 1 到 n. 每个单位拥有三项属性: si: 初始法力. mi: 最大法力上限. ri: 每秒中法力回复速度. 现在你操纵一个毁灭者, ...
- NGUI中以添加摄像机的方式实现SCROLL LIST
1.添加多一个UI ROOT对象 2.把CAMERAER对象移至ROOT对象成为其直接子对象, 3.为CAMERAER对象添加UIVIEWPORT组件,并把其SOURCE CAMERA设置为主相机,设 ...
- android Paint属性
** * Paint类介绍 * * Paint即画笔,在绘图过程中起到了极其重要的作用,画笔主要保存了颜色, * 样式等绘制信息,指定了如何绘制文本和图形 ...
- POSTMAN编写文档
第一步:创建文件夹: 同时创建全局变量: 第二步:创建分组文件夹: 第三步:添加请求: 类似正常调试,然后多了一步保存: 保存: 请求方式发生相应变化,同时颜色也发生变化,说明保存成功: ====== ...
- 有向图最小路径覆盖方法浅析、证明 //hdu 3861
路径覆盖就是在图中找一些路径,使之覆盖了图中的所有顶点,且任何一个顶点有且只有一条路径与之关联. 对于一个有向无环图怎么求最小路径覆盖? 先构造二分图: 对于原图,先拆点,吧每个点i拆成ii,iii. ...
- Linux 的信号和线程
什么是线程 线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元.一个标准的线程由线程ID,当前指令指针(PC),寄存器集合和堆栈组成,每一个程序都至少 ...