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相关推荐

  1. 大数据入门基础系列之初步认识大数据生态系统圈(博主推荐)

    不多说,直接上干货! 之前在微信公众平台里写过 大数据入门基础系列之初步认识hadoop生态系统圈 http://mp.weixin.qq.com/s/KE09U5AbFnEdwht44FGrOA 大 ...

  2. Spark快速大数据分析——Scala语言基础(壹)

    Spark快速大数据分析--Scala语言基础(壹) 文章目录 Spark快速大数据分析--Scala语言基础(壹) 前记 Scala的历史 环境搭建: 1.SBT构建工具和REPL: 2.使用IDE ...

  3. Spark —— 闪电般快速的统一分析引擎 —— 入门基础知识

    Spark 入门基础知识 Spark 的特点 速度快 使用方便 通用 兼容 Spark 基础 下载 独立部署模式(Standalone) 弹性分布式数据集 Scala shell 1. 数组中的最值: ...

  4. Python培训入门基础知识学什么?

    Python培训基础知识主要是针对一些零基础的同学安排的,虽说Python是相对比较简单的一门编程语言,但是没有基础的同学还是要进行系统的学习,那么Python培训入门基础知识学什么呢?来看看下面小编 ...

  5. JSON入门基础知识

    2019独角兽企业重金招聘Python工程师标准>>> JSON入门基础 1.JSON定义 JSON:JavaScript 对象表示法(JavaScript Object Notat ...

  6. JSP WEB开发入门基础到高手进阶教程002

    JSP WEB开发入门基础到高手进阶教程 -------开发入门 JSP与微软的Active Server Pages 兼容,但它是使用类似HTML的卷标以及Java程序代码段而不是VBScript. ...

  7. NLP汉语自然语言处理入门基础知识介绍

    NLP汉语自然语言处理入门基础知识介绍 自然语言处理定义: 自然语言处理是一门计算机科学.人工智能以及语言学的交叉学科.虽然语言只是人工智能的一部分(人工智能还包括计算机视觉等),但它是非常独特的一部 ...

  8. 负荷计算的时候assert失败_负荷计算的入门基础知识,小白入门必备!

    负荷计算是电气设计人员必须掌握的一必修课,选导体.设备还有保护开关的选择,电网系统分析,都离不开负荷计算的内容,为此小编特意总结9个负荷计算的入门基础知识,分享给大家,希望能在工作和学习中作为一份参考 ...

  9. 7.1 pdo 宝塔面板php_小白入门基础傻瓜式操作PHP面板安装使用_Bt宝塔面板

    ​ 小白入门基础傻瓜式操作PHP面板安装使用--Bt宝塔面板 从购买服务器到安装面板在到搭建网站(最基础的教程,以后会延伸到部署项目) 不用写代码谁都可以做到搭建自己的网站(PHP类)还有小程序,只要 ...

最新文章

  1. 有返回值的多线程demo
  2. signature=16ceadeb007b12c6b3bcab834073ab21,Distributed Backscattering
  3. 键盘发展简史:144年独孤求败的QWERT键盘
  4. mysql ip to int_ip网段转换程序(把ip地址转换成相对就的整数)
  5. SQL Server 的存储过程[转]
  6. 《机器人学导论》约翰 第二章
  7. Mac 修改VIM中C语言函数高亮显示
  8. python调用谷歌地图_谷歌地图API Python/R
  9. Labwindows/CVI 编写CAN通讯的上位机
  10. 《 没有业绩怎么写好年终总结.ppt 》
  11. Kettle_使用资源库功能把ktr元数据统一存储到数据库中
  12. 智慧工地具有哪些社会意义?
  13. 网络代理服务器的设计与实现
  14. OpenCV图像处理形态学操作腐蚀Erode与膨胀Dilate
  15. 由于高精度事件计时器(HPET)驱动过时导致AMD机器装Win10的卡死蓝屏问题记录
  16. Delphi重建与删除Foxpro(DBF)数据库索引文件CDX
  17. php 可视化编辑建站源码,CmsEasy可视化编辑商城系统 v7.3.1
  18. CISCO 640-875 认证题库 更新
  19. 西北农林科技大学linux实验报告,西北农林科技大学 linux考试复习提纲
  20. 电子信息工程专业概论_【专业简介】电子信息工程

热门文章

  1. 特征工程(四)HashingVectorizer
  2. ACL2022引入滚动审稿机制,Deadline不足一个月啦
  3. 她,诗人拜伦之女,英国数学家,历史上第一位程序员
  4. 放大招了,送一波来自 Facebook、Google、网易、阿里的学习福利!
  5. 刷题2个月,终于进了梦寐以求的大厂,数据结构和算法太TM重要了!
  6. 中科院博导: 读博士感到痛苦的五个原因
  7. 哈佛终身教授:年轻人如何做科研?
  8. 那些为了学技术而离婚、私奔的大佬们运营的公众号有哪些?
  9. 聚类分析案例:探究用户对物品类别的喜好细分降维
  10. 如何入门论文阅读综述小解答