`

Scala基础(二)

 
阅读更多

Scala基础(二)

单例类

一个object是一个只有一个实例的类,它在被引用的时候才创建,像一个lazy val。

作为一个顶层的值,一个object就是一个单例。

作为一个封闭类的成员或局部变量,它表现的就很像一个lazy val。

定义一个单例对象

一个object是一个值,定义一个object就像一个类,只是用object关键字

 

object Box

 这里有一个简单的只有一个方法的object。

package logging

object Logger {
  def info(message: String): Unit = println(s"INFO: $message")
}

 这个info方法可以在程序的任意地方被引入。像这样创建工具方法是单例对象的常见用例。让我们看看如何在另外的包中使用info

import logging.Logger.info

class Project(name: String, daysToComplete: Int)

class Test {
  val project1 = new Project("TPS Reports", 1)
  val project2 = new Project("Website redesign", 5)
  info("Created projects")  // Prints "INFO: Created projects"
}

 由于这个import logging.Logger.info import语句,info方法就变得可见了。

 

import需要一个稳定路径(stable path)指向被引入的符号,一个object就是一个稳定路径。

注意:如果一个object不是顶层的,而是嵌入在另一个class或object中。那么这个object就是和其他任何成员一样的路径相关(path-dependent)的。这意味着给定两种饮料,class Milk和class OrangeJuice,一个类成员object NutritionInfo 依赖于封闭实例,milk或orange juice。milk.NutritionInfo和oj.NutritionInfo是完全不同的。

伴随对象(Companion object)

和类的名字一样的对象称为伴随对象(companion object)。相反的,这个类是这个对象的伴随类(companion class)。一个伴随类或伴随对象可以访问它的同伴的私有成员。为伴随类中和特定对象无关的方法和值用一个伴随对象。

import scala.math._

case class Circle(radius: Double) {
  import Circle._
  def area: Double = {
    calculateArea(radius)
  }
}

object Circle {
  private def calculateArea(radius: Double): Double = {
    Pi * pow(radius, 2.0)
  }

  def main(args: Array[String]): Unit = {
    val circle1 = new Circle(5.0)
    println(circle1.area)
  }
}

 

类Circle有一个对于每个实例都不一样的成员area,单例object Circle有一个对于每个实例都可用的方法calculateArea。

伴随对象也可以包含工厂方法(factory method):

package tour.singleton_objects

class Email(val username: String, val domainName: String)

object Email {
  def fromString(emailString: String): Option[Email] = {
    emailString.split('@') match {
      case Array(a, b) => Some(new Email(a, b))
      case _ => None
    }
  }

  def main(args: Array[String]): Unit = {
    val scalaCenterEmail = Email.fromString("scala.center@epfl.ch")
    scalaCenterEmail match {
      case Some(email) => {
        println(
          s"""Registered an email
             |Username: ${email.username}
             |Domain name: ${email.domainName}
           """)
      }
      case None => {
        println("Error: could not parse email")
      }
    }
  }
}

 

object Email包含一个工厂方法fromString,从一个字符串创建一个Email实例。考虑到解析错误,我们返回一个Option[Email]。

注意:如果一个类或对象有一个伴随,它们必须都定义在同一个文件中。为了在REPL中定义伴随,可以在同一行定义它们,或者进入:paste模式。

 

Java中的static成员可以作为Scala中伴随对象的普通成员的模型。

当使用Java代码中的伴随对象时,成员将会在一个伴随类中用static修饰符定义。这个称谓static forwarding。即使你没有为你自己定义一个伴随类也会发生这种情况。

 

正则表达式匹配

正则表达式是可以用来在数据中查找模式的字符串。任何字符串都可以通过 .r 方法转变成正则表达式。

package tour.regex

import scala.util.matching.Regex

object RegexExample {

  def main(args: Array[String]): Unit = {
    val numberPattern: Regex = "[0-9]"r

    numberPattern.findFirstMatchIn("awesomepassword") match {
      case Some(_) => println("Password OK")
      case None => println("Password must contain a number")
    }
  }
}

 

在上面的例子中,numberPattern是一个Regex,我们用它来确保密码中包含数字。

我们也可以用小括号来搜索正则表达式的组(group)。

package tour.regex

import scala.util.matching.Regex

object RegexExample {

  def regexTest() = {
    val numberPattern: Regex = "[0-9]"r

    numberPattern.findFirstMatchIn("awesomepassword") match {
      case Some(_) => println("Password OK")
      case None => println("Password must contain a number")
    }
  }

  def regexGroupTest(): Unit = {
    val keyValuePattern: Regex = "([0-9a-zA-Z-#() ]+): ([0-9a-zA-Z-#() ]+)".r

    val input: String =
      """background-color: #A03300;
        |background-image: url(img/header100.png);
        |background-position: top center;
        |background-repeat: repeat-x;
        |background-size: 2160px 108px;
        |margin: 0;
        |height: 108px;
        |width: 100%;""".stripMargin

    for (patternMatch <- keyValuePattern.findAllMatchIn(input)) {
      println(s"key: ${patternMatch.group(1)} value: ${patternMatch.group(2)}")

      /**
        * key: background-color value: #A03300
        * key: background-image value: url(img
        * key: background-position value: top center
        * key: background-repeat value: repeat-x
        * key: background-size value: 2160px 108px
        * key: margin value: 0
        * key: height value: 108px
        * key: width value: 100
        */
    }
  }

  def main(args: Array[String]): Unit = {
    regexTest()
    regexGroupTest()
  }
}

 

这里我们解析字符串中键值对,每个匹配有一组子匹配。

 

提取对象(Extractor Objects)

一个extractor object是一个有一个unapply方法的对象。apply方法像一个构造函数,接受参数并创建对象,但是unapply接受一个对象,然后尝试恢复参数。这个在pattern matching和部分函数(partial function)中经常用到。

 

package tour.class_related

import scala.util.Random

object CustomerID {

  def apply(name: String) = {
    println("call apply")
    s"$name--${Random.nextLong()}"
  }

  def unapply(customerID: String): Option[String] = {
    println("call unapply")
    val name = customerID.split("--").head
    if (name.nonEmpty) Some(name) else None
  }

  def main(args: Array[String]): Unit = {
    val customerID = CustomerID("Sukyoung")
    println("next call match")
    customerID match {
      case CustomerID(name) => println(name)
      case _ => println("Could not extract a CustomerID")
    }
  }
}
 

 

上面这段程序会打印:

call apply

next call match

call unapply

Sukyoung

 

apply方法从一个name创建了一个CustomerID, unapply完成了相反的动作,把name找回来了。当我们调用CustomerID("Sukyoung")时,这是调用CustomerID.apply("Sukyoung")的简写语法。当我们调用case CustomerID(name) => println(name)时,我们调用了unapply方法。

unapply方法也可以被用于赋值。

val customer2ID = CustomerID("Nico")
val CustomerID(name) = customer2ID
println(name)  // prints Nico

 

这等于val name = CustomerID.unapply(customer2ID).get,如果没有匹配的,会抛出scala.MatchError

val CustomerID(name2) = "--asdfasdfasdf"

 

unapply的返回值应该从以下选项中选择一个:

  • 如果只是一个测试,可以放回一个Boolean。例如case even()
  • 如果他们返回类型的一个次值(sub-value),返回一个Option[T]
  • 如果你想要放回多个次值T1,T2,...,Tn,用一个Option元组将它们组合起来Option[(T1,T2,...,Tn)]

有的时候,次值的数量不是固定的,我们想要返回一个列表(sequence)。为了这个原因,你也可以通过unapplySeq来定义模式,返回Option[Seq[T]]。这个机制在模式case List(x1,...,xn)的实例中使用。

分享到:
评论

相关推荐

    about云spark开发基础之Scala快餐第二版.pdf

    about云spark开发基础之Scala快餐第二版.pdf

    快学scala习题及答案详解

    快学scala习题、答案、详细解答 快学scala第一章习题答案.doc 快学scala第二章习题答案.doc 快学scala第三章习题答案.doc ......

    Scala实用指南

    本书共分为 4 个部分:第一部分详细介绍 Scala 的一些基础知识,并和 Java 中的相关概 念进行了参照,方便读者快速上手 Scala;第二部分进一步介绍 Scala 的一些中级知识,以及 与 Java 的一些差异点,方便读者编写...

    scala编程 第二版(高清+书签)

    豆瓣评分8.0的好书!!!学习scala的必读读物之一,由浅入深,是学习spark的重要基础之一!!!本书高清完整,带目录。

    SCALA编程思想 原书第2版 PDF 下载

    本书介绍Scala的基础特性,采用短小精悍的“原子”解构Scala语言的元素和方法。一个“原子”即为一个小型知识点,通过代码示例引导读者逐步领悟Scala的要义,结合练习鼓励读者在实践中读懂并写出地道的Scala代码。...

    Scala语言视频百度网盘

    第01阶段 :Scala 入门 第02阶段:Scala 的函数式编程 第03阶段:Scala 的面向对象编程 第04阶段:Scala的高级基础一 第05阶段:Scala的高级基础二

    快学scala 第2版 英文版

    高清pdf原版 非网页版 非整合版 2016.12 Scala for the Impatient, 2nd Edition

    《Spark编程基础及项目实践》课后习题及答案4.pdf

    《Spark编程基础及项目实践》课后习题及答案4.pdf《Spark编程基础及项目实践》课后习题及答案4.pdf《Spark编程基础及项目实践》课后习题及答案4.pdf《Spark编程基础及项目实践》课后习题及答案4.pdf《Spark编程基础...

    Scala快速从入门到神坑

    二、 Scala安装 1. 在Windows操作系统中安装Scala 2. 在Linux操作系统中安装Scala 三、Scala 基础部分 3.1 声明值和变量 3.1.1 val变量 3.1.2 var 变量 3.2 级别数据类型和操作 3.2.1 级别数据类型 3.2.2 操作符 3.3...

    scala从入门到精通技术教学视频

    第二章 变量和数据类型 00.导学 01.输出语句和分号 02.Scala中的常量 03.Scala中的变量 04.字符串的定义 05.惰性赋值 06.标识符 07.数据类型 08.类型转换 09.值类型和String类型之间的相互转换 10.键盘录入功能 11....

    快学 scala 中文版 带完整目录

    第1章 基础 A1 1 1.1 Scala解释器 1 1.2 声明值和变量 4 1.3 常用类型 5 1.4 算术和操作符重载 7 1.5 关于方法调用 8 1.6 apply方法 9 1.7 Scaladoc 11 练习 16 第2章 控制结构和函数 A1 19 2.1 条件...

    《Spark 编程基础》 教材讲义 厦门大学 林子雨

    《Spark 编程基础 》 教材讲义 厦门大学计算机科学系 林子雨 PPT 版本号:2018 年1月

    scala实用指南

    本书共分为4个部分:第一部分详细介绍Scala的一些基础知识,并和Java中的相关概念进行了参照;第二部分进一步介绍Scala的一些中级知识,以及与Java的一些差异点;第三部分介绍在Scala中如何进行并发编程,并务实地...

    scala-native-bindgen:Scala本机绑定生成器

    它建立在clang和Libtooling的基础上,因此尊重clang-tools的约定。 用法 调用该工具非常容易,您需要指定文件和创建的绑定的名称。 ./scalaBindgen /usr/include/uv.h -name uv -- 野蛮地运行前面的命令还会产生...

    lamp:深度学习和科学计算库,具有用于Scala编程语言的本地CPU和GPU后端

    灯 Lamp是一个Scala库,用于深度学习和科学计算。 它具有本机CPU和GPU后端,并在堆外内存上运行。 灯的灵感来自。 lamp的基础是的是手电筒的C ++张量后端()。 结果,灯泡使用了快速的CPU和GPU代码,并将其数据存储...

    大数据教程全面深入spark视频教程

    上百节课详细讲解,需要的小伙伴自行百度网盘下载,链接见附件,永久有效。...适合给,有java,scala基础,想往大数据spark机器学习这块发展 适合给想学习spark,往数据仓库,大数据挖掘机器学习,方向发展的学员

    Spark集群及开发环境搭建

    二、 集群环境信息 2 三、 机器安装 3 1. 安装虚拟机VirtualBox 3 2. 安装CentOs7 3 四、 基础环境搭建(hadoop用户下) 7 1. 机器名HostName 7 2. 关闭防火墙 7 3. 系统更新及常用工具安装 8 4. IP配置 8 ...

    Spark集群及开发环境搭建(完整版)

    二、 集群环境信息 2 三、 机器安装 2 1. 安装虚拟机VirtualBox 2 2. 安装CentOs7 2 四、 基础环境搭建(hadoop用户下) 6 1. 机器名HostName 6 2. 关闭防火墙 6 3. 系统更新及常用工具安装 7 4. IP配置 8 ...

    spark考试练习题含答案.rar

    spark考试练习题含答案.rar

Global site tag (gtag.js) - Google Analytics