apply和unapply:

apply方法经常用在伴生对象中,用来构造对象而不用显式地使用new。

unapply是当做是伴生对象的apply方法的反向操作。apply方法接受构造参数,然后将他们变成对象。而unapply方法接受一个对象,然后从中提取值。unapply方法返回的是一个Option.

  1. object ScalaRunner {
  2. def main(args: Array[String]): Unit = {
  3. testApply2()
  4. testApplyUnApply()
  5. testCaseClass()
  6. testNumber()
  7. testUnapplyCheck()
  8. }
  9.  
  10. private def testUnapplyCheck(): Unit = {
  11. "Hello World fdf" match {
  12. case Name(first, last@IsCompound()) => println(s"first: ${first}, last: ${last}")
  13. }
  14. }
  15.  
  16. private def testNumber() = {
  17. val Number(n) = "12345"
  18. println(s"n: ${n}")
  19. }
  20.  
  21. private def testCaseClass(): Unit = {
  22. val p: Person = Person("Sky", 20)
  23. p match {
  24. case Person(name, 20) => println(s"name: ${name}")
  25. }
  26. }
  27.  
  28. private def testApplyUnApply() {
  29. val nameObj = Name("hello", "world")
  30. println(s"a: ${nameObj.a}, b: ${nameObj.b}")
  31.  
  32. val Name(arg11, arg12) = "Hello World"
  33. println(s"arg11: ${arg11}, arg12: ${arg12}")
  34.  
  35. val Name(arg21, arg22) = Name("hello", "world").toString
  36. println(s"arg21: ${arg21}, arg22: ${arg22}")
  37.  
  38. }
  39.  
  40. private def testApply(): Unit = {
  41. Name()
  42. (new Name) ()
  43. (new Name()) ()
  44. Name()()
  45.  
  46. }
  47.  
  48. private def testApply2(): Unit = {
  49. Name(1)
  50. (new Name()) (1)
  51. (new Name) (1)
  52. Name(1)(1)
  53. }
  54. }
  55.  
  56. case class Person(val name: String, val age: Int)
  57.  
  58. object Number {
  59. def unapply(input: String): Option[Int] = {
  60. try{
  61. Some(Integer.parseInt(input.trim))
  62. } catch {
  63. case ex: NumberFormatException => None
  64. }
  65. }
  66.  
  67. }
  68.  
  69. class Name {
  70. var a = ""
  71. var b = ""
  72.  
  73. def this(a: String, b: String){
  74. this
  75. println("Call class construct.")
  76. this.a = a
  77. this.b = b
  78. }
  79.  
  80. def apply() = {
  81. println("Call class apply.")
  82. }
  83.  
  84. def apply(i: Int) = {
  85. println(s"Call class apply ${i}.")
  86. }
  87.  
  88. override def toString: String = {
  89. a + " " + b
  90. }
  91.  
  92. }
  93.  
  94. object Name {
  95.  
  96. def apply(): Name = {
  97. println("Call object apply.")
  98. new Name()
  99. }
  100.  
  101. def apply(i: Int): Name = {
  102. println(s"Call object apply ${i}.")
  103. new Name()
  104. }
  105.  
  106. def apply(a: String, b: String): Name = {
  107. println(s"Call object apply.")
  108. new Name(a, b)
  109. }
  110.  
  111. def unapply(input: String): Option[(String, String)] = {
  112. println(s"Call object unapply.")
  113. val pos = input.indexOf(" ")
  114. if(pos == -1) None
  115. else Some((input.substring(0, pos), input.substring(pos + 1)))
  116. }
  117.  
  118. }
  119.  
  120. object IsCompound {
  121. def unapply(input: String) = {
  122. println(s"Call IsCompound unapply ${input}.")
  123. input.contains(" ")
  124. }
  125. }

运行结果:

快学Scala 第二十二课 (apply和unapply)的更多相关文章

  1. 快学Scala 第十二课 (抽象类, 抽象字段, 提前定义)

    抽象类: Scala 抽象类中,抽象方法不需要使用abstract. 在子类中重写超类抽象方法时,不需要使用override. abstract class Person { def say(s: S ...

  2. 快学Scala 第十九课 (trait的abstract override使用)

    trait的abstract override使用: 当我看到abstract override介绍的时候也是一脸懵逼,因为快学scala,只介绍了因为TimestampLogger中调用的super ...

  3. 快学Scala 第二十课 (trait的构造顺序)

    trait的构造顺序: 首先调用超类构造器 特质构造器在超类构造器之后,类构造器之前执行 特质从左向右被构造 每个特质当中,父特质先被构造 如果多个特质共有一个父特质,而那个父特质已经被构造,则不会被 ...

  4. 快学Scala 第十四课 (读取行,读取字符, 控制台读取)

    读取行: import scala.io.Source object FileReader { def main(args: Array[String]): Unit = { val source = ...

  5. 快学Scala 第十八课 (trait多继承)

    trait多继承: trait的继承并不像类拥有相同的含义!在下面这个例子中,如果还是运用类的继承的思想,那么运行结果将是什么也没有. trait Logged { def log(msg: Stri ...

  6. 快学Scala 第十六课 (shell调用,正则表达式,正则表达式组,stripMargin妙用)

    shell调用:(管道符前加#号,执行shell用!) import sys.process._ "ls -al" #| "grep x" ! 正则表达式:(r ...

  7. 快学Scala 第十五课 (二进制读取文件,写文件,访问目录,序列化)

    二进制读取文件: val file = new File("F:\\scalaWorkspace\\ScalaLearning\\files\\test.txt") val in ...

  8. NeHe OpenGL教程 第二十二课:凹凸映射

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. 快学Scala 第二课 (apply, if表达式,循环,函数的带名参数,可变长参数,异常)

    apply方法是Scala中十分常见的方法,你可以把这种用法当做是()操作符的重载形式. 像以上这样伴生对象的apply方法是Scala中构建对象的常用手法,不再需要使用new. if 条件表达式的值 ...

随机推荐

  1. B-Quadratic equation_2019牛客暑期多校训练营(第九场)

    题意 解下列方程 \((x+y) \equiv b \ mod \ p\) \((x\ *\ y) \equiv c \ mod \ p\) 题解 \(y = b-x\) 带入二式 \(x * (b- ...

  2. 阿里云机器维护-gitlab Forbidden

    gitlab这台机子运行了一两年了,今天突然拉代码不能拉了,看了下接口403 登录网页 Forbidden 看了下是前两天挖矿病毒引发的,大致因为大量请求导致ip被封了 我们只要把这台机子加入配置白名 ...

  3. 微信小程序集成腾讯云 IM SDK

    微信小程序集成腾讯云 IM SDK 1.背景 因业务功能需求需要接入IM(即时聊天)功能,一开始想到的是使用 WebSocket 来实现这个功能,然天意捉弄(哈哈)服务器版本太低不支持 wx 协议(也 ...

  4. Factory Method工厂方法模式

    定义一个用于创建对象的接口,让子类决定将哪一个类实例化.Factory Method使一个类的实例化延迟到其子类,属于创建型模式 在此模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类负责生产 ...

  5. Winform中实现ZedGraph曲线图的图像复制到剪切板、打印预览、获取图片并保存、另存为的功能

    场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  6. 大数据平台搭建 - cdh5.11.1 - hbase集群搭建

    一.简介 HBase是一种构建在HDFS之上的分布式.面向列的存储系统.在需要实时读写.随机访问超大规模数据集时,可以使用HBase. 尽管已经有许多数据存储和访问的策略和实现方法,但事实上大多数解决 ...

  7. HTML 框架导航

    初次学习HTML,在www.w3school.com.cn看到了框架导航,上面的例子没有看懂所以搜了一下相应的问题,最后弄懂了怎么实现同一界面下的框架导航. 首先是www.w3school.com.c ...

  8. 由于找不到opencv_world***d.dl,无法继续执行代码。重新安装程序可能会解决此问题。关于opencv使用imshow函数闪退解决方法等问题

    1.将缺失的文件放到程序根目录的debug中 2.将Debug x64下的附加依赖项改为只有后缀为d.lib的那个库文件,去除另一个,问题就这么解决了,虽然我也不知道加上另一个为什么就会闪退

  9. Docker学习之docker常用命令

    docker ps -a 表示所有容器 docker pull 获取image docker build 创建image docker run 运行container docker images 列出 ...

  10. [Advanced Python] 13 - "Decorator": syntactic sugar

    单独一章复习:Python 函数装饰器,廖雪峰讲装饰器 基本概念 函数作为变量 从函数中返回函数 子函数写在外面貌似也可以,可这样就少了“封装性”. def greet(): return " ...