scala入门基础2
scala基础之二
课程内容:
- apply方法
- 单例对象
- 函数即对象
- 包
- 模式匹配
- 样本类
- try-catch-finally
apply 方法
当类或对象有一个主要用途的时候,apply方法为你提供了一个很好的语法糖。
scala> class Foo {}
defined class Fooscala> object FooMaker {| def apply() = new Foo| }
defined module FooMakerscala> val newFoo = FooMaker()
newFoo: Foo = Foo@5b83f762
或scala> class Bar {| def apply() = 0| }
defined class Barscala> val bar = new Bar
bar: Bar = Bar@47711479scala> bar()
res8: Int = 0
在这里,我们实例化对象看起来像是在调用一个方法。以后会有更多介绍!
单例对象
单例对象用于持有一个类的唯一实例。通常用于工厂模式。
object Timer {var count = 0def currentCount(): Long = {count += 1count}
}
可以这样使用:
scala> Timer.currentCount()
res0: Long = 1
单例对象可以和类具有相同的名称,此时该对象也被称为“伴生对象”。我们通常将伴生对象作为工厂使用。
下面是一个简单的例子,可以不需要使用’new’来创建一个实例了。
class Bar(foo: String)object Bar {def apply(foo: String) = new Bar(foo)
}
函数即对象
在Scala中,我们经常谈论对象的函数式编程。这是什么意思?到底什么是函数呢?
函数是一些特质的集合。具体来说,具有一个参数的函数是Function1特质的一个实例。这个特质定义了apply()语法糖,让你调用一个对象时就像你在调用一个函数。
scala> object addOne extends Function1[Int, Int] {| def apply(m: Int): Int = m + 1| }
defined module addOnescala> addOne(1)
res2: Int = 2
这个Function特质集合下标从0开始一直到22。为什么是22?这是一个主观的魔幻数字(magic number)。我从来没有使用过多于22个参数的函数,所以这个数字似乎是合理的。
apply语法糖有助于统一对象和函数式编程的二重性。你可以传递类,并把它们当做函数使用,而函数本质上是类的实例。
这是否意味着,当你在类中定义一个方法时,得到的实际上是一个Function的实例?不是的,在类中定义的方法是方法而不是函数。在repl中独立定义的方法是Function的实例。
类也可以扩展Function,这些类的实例可以使用()调用。
scala> class AddOne extends Function1[Int, Int] {| def apply(m: Int): Int = m + 1| }
defined class AddOnescala> val plusOne = new AddOne()
plusOne: AddOne = <function1>scala> plusOne(1)
res0: Int = 2
可以使用更直观快捷的extends (Int => Int)代替extends Function1[Int, Int]
class AddOne extends (Int => Int) {def apply(m: Int): Int = m + 1
}
包
你可以将代码组织在包里。
package com.twitter.example
在文件头部定义包,会将文件中所有的代码声明在那个包中。
值和函数不能在类或单例对象之外定义。单例对象是组织静态函数(static function)的有效工具。
package com.twitter.exampleobject colorHolder {val BLUE = "Blue"val RED = "Red"
}
现在你可以直接访问这些成员
println("the color is: " + com.twitter.example.colorHolder.BLUE)
注意在你定义这个对象时Scala解释器的返回:
scala> object colorHolder {| val Blue = "Blue"| val Red = "Red"| }
defined module colorHolder
这暗示了Scala的设计者是把对象作为Scala的模块系统的一部分进行设计的。
模式匹配
这是Scala中最有用的部分之一。
匹配值
val times = 1times 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"
}
注意我们是怎样获取变量’i’的值的。
在最后一行指令中的_是一个通配符;它保证了我们可以处理所有的情况。
否则当传进一个不能被匹配的数字的时候,你将获得一个运行时错误。我们以后会继续讨论这个话题的。
参考 Effective Scala 对什么时候使用模式匹配 和 模式匹配格式化的建议. A Tour of Scala 也描述了 模式匹配
匹配类型
你可以使用 match来分别处理不同类型的值。
def bigger(o: Any): Any = {o match {case i: Int if i < 0 => i - 1case i: Int => i + 1case d: Double if d < 0.0 => d - 0.1case d: Double => d + 0.1case 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"
}
(⊙o⊙)哦,太痛苦了。幸好Scala提供了一些应对这种情况的有效工具。
样本类 Case Classes
使用样本类可以方便得存储和匹配类的内容。不用new关键字就可以创建它们。
scala> case class Calculator(brand: String, model: String)
defined class Calculatorscala> val hp20b = Calculator("HP", "20b")
hp20b: Calculator = Calculator(hp,20b)
样本类基于构造函数的参数,自动地实现了相等性和易读的toString方法。
scala> val hp20b = Calculator("HP", "20b")
hp20b: Calculator = Calculator(hp,20b)scala> val hp20B = Calculator("HP", "20b")
hp20B: Calculator = Calculator(hp,20b)scala> hp20b == hp20B
res6: Boolean = true
样本类也可以像普通类那样拥有方法。
使用样本类进行模式匹配
样本类就是被设计用在模式匹配中的。让我们简化之前的计算器分类器的例子。
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)
}
最后一句也可以这样写
case Calculator(_, _) => "Calculator of unknown type"
或者我们完全可以不将匹配对象指定为Calculator类型
case _ => "Calculator of unknown type"
或者我们也可以将匹配的值重新命名。
case c@Calculator(_, _) => "Calculator: %s of unknown type".format(c)
异常
Scala中的异常可以在try-catch-finally语法中通过模式匹配使用。
try {remoteCalculatorService.add(1, 2)
} catch {case e: ServerIsDownException => log.error(e, "the remote calculator service is unavailable. should have kept your trusty HP.")
} finally {remoteCalculatorService.close()
}
try也是面向表达式的
val result: Int = try {remoteCalculatorService.add(1, 2)
} catch {case e: ServerIsDownException => {log.error(e, "the remote calculator service is unavailable. should have kept your trusty HP.")0}
} finally {remoteCalculatorService.close()
}
这并不是一个完美编程风格的展示,而只是一个例子,用来说明try-catch-finally和Scala中其他大部分事物一样是表达式。
当一个异常被捕获处理了,finally块将被调用;它不是表达式的一部分。
scala入门基础2相关推荐
- 大数据入门基础系列之初步认识大数据生态系统圈(博主推荐)
不多说,直接上干货! 之前在微信公众平台里写过 大数据入门基础系列之初步认识hadoop生态系统圈 http://mp.weixin.qq.com/s/KE09U5AbFnEdwht44FGrOA 大 ...
- Spark快速大数据分析——Scala语言基础(壹)
Spark快速大数据分析--Scala语言基础(壹) 文章目录 Spark快速大数据分析--Scala语言基础(壹) 前记 Scala的历史 环境搭建: 1.SBT构建工具和REPL: 2.使用IDE ...
- Spark —— 闪电般快速的统一分析引擎 —— 入门基础知识
Spark 入门基础知识 Spark 的特点 速度快 使用方便 通用 兼容 Spark 基础 下载 独立部署模式(Standalone) 弹性分布式数据集 Scala shell 1. 数组中的最值: ...
- Python培训入门基础知识学什么?
Python培训基础知识主要是针对一些零基础的同学安排的,虽说Python是相对比较简单的一门编程语言,但是没有基础的同学还是要进行系统的学习,那么Python培训入门基础知识学什么呢?来看看下面小编 ...
- JSON入门基础知识
2019独角兽企业重金招聘Python工程师标准>>> JSON入门基础 1.JSON定义 JSON:JavaScript 对象表示法(JavaScript Object Notat ...
- JSP WEB开发入门基础到高手进阶教程002
JSP WEB开发入门基础到高手进阶教程 -------开发入门 JSP与微软的Active Server Pages 兼容,但它是使用类似HTML的卷标以及Java程序代码段而不是VBScript. ...
- NLP汉语自然语言处理入门基础知识介绍
NLP汉语自然语言处理入门基础知识介绍 自然语言处理定义: 自然语言处理是一门计算机科学.人工智能以及语言学的交叉学科.虽然语言只是人工智能的一部分(人工智能还包括计算机视觉等),但它是非常独特的一部 ...
- 负荷计算的时候assert失败_负荷计算的入门基础知识,小白入门必备!
负荷计算是电气设计人员必须掌握的一必修课,选导体.设备还有保护开关的选择,电网系统分析,都离不开负荷计算的内容,为此小编特意总结9个负荷计算的入门基础知识,分享给大家,希望能在工作和学习中作为一份参考 ...
- 7.1 pdo 宝塔面板php_小白入门基础傻瓜式操作PHP面板安装使用_Bt宝塔面板
小白入门基础傻瓜式操作PHP面板安装使用--Bt宝塔面板 从购买服务器到安装面板在到搭建网站(最基础的教程,以后会延伸到部署项目) 不用写代码谁都可以做到搭建自己的网站(PHP类)还有小程序,只要 ...
最新文章
- 有返回值的多线程demo
- signature=16ceadeb007b12c6b3bcab834073ab21,Distributed Backscattering
- 键盘发展简史:144年独孤求败的QWERT键盘
- mysql ip to int_ip网段转换程序(把ip地址转换成相对就的整数)
- SQL Server 的存储过程[转]
- 《机器人学导论》约翰 第二章
- Mac 修改VIM中C语言函数高亮显示
- python调用谷歌地图_谷歌地图API Python/R
- Labwindows/CVI 编写CAN通讯的上位机
- 《 没有业绩怎么写好年终总结.ppt 》
- Kettle_使用资源库功能把ktr元数据统一存储到数据库中
- 智慧工地具有哪些社会意义?
- 网络代理服务器的设计与实现
- OpenCV图像处理形态学操作腐蚀Erode与膨胀Dilate
- 由于高精度事件计时器(HPET)驱动过时导致AMD机器装Win10的卡死蓝屏问题记录
- Delphi重建与删除Foxpro(DBF)数据库索引文件CDX
- php 可视化编辑建站源码,CmsEasy可视化编辑商城系统 v7.3.1
- CISCO 640-875 认证题库 更新
- 西北农林科技大学linux实验报告,西北农林科技大学 linux考试复习提纲
- 电子信息工程专业概论_【专业简介】电子信息工程