Scala Overview

Scala is object-oriented

  • Every user-defined class in Scala implicitly extends the trait scala.ScalaObject.
  • If Scala is used in the context of a Java runtime environment, then scala.AnyRef corresponds to java.lang.Object.

Scala is Functional

Anonymous Function Syntax

  • eg:

    (x: Int) => x + 1
    This is a shorthand for the following anonymous class definition:
    new Function1[Int, Int] {
    def apply(x: Int): Int = x + 1
    }
  • It is also possible to define functions with multiple parameters:

    (x: Int, y: Int) => "(" + x + ", " + y + ")"
    
  • or even with no parameter:

    () => { System.getProperty("user.dir") }

Higher-Order Functions

  • Higher-order functions are those who can take functions as parameters, or whose result is a function.
  • Eg: Function apply which takes another function f and a value v and applies function f to v:
    def apply(f: Int => String, v: Int) = f(v)
  • A more complicated example:
    class Decorator(left: String, right: String) {
    def layout[A](x: A) = left + x.toString() + right
    } object FunTest extends Application {
    def apply(f: Int => String, v: Int) = f(v)
    val decorator = new Decorator("[", "]")
    println(apply(decorator.layout, 7))
    }

  In this example, the method decorator.layout is coerced automatically to a value of type Int => String as required by method apply. Please note that the method decorator.layout is a polymorphic method(i.e. it abstracts over some of its signature types) and the Scala compiler has to instantiate its method type first appropriately.

Nested Functions

  • In Scala it is possible to nest function definitions.
  • Eg:
    object FilterTest extends Application {
    def filter(xs: List[Int], threshold: Int) = {
    def process(ys: List[Int]): List[Int] =
    if (ys.isEmpty) ys
    else if (ys.head < threshold) ys.head :: process(ys.tail)
    else process(ys.tail)
    process(xs)
    }
    println(filter(List(1, 9, 2, 8, 3, 7, 4), 5))
    }

Currying

  • Methods may define multiple parameter lists. When a method is called with a fewer number of parameter lists, then this will yield a function taking the missing parameter lists as its arguments.
  • Eg:
    object CurryTest extends Application {
    def filter(xs: List[Int], p: Int => Boolean): List[Int] =
    if (xs.isEmpty) xs
    else if (p(xs.head)) xs.head :: filter(xs.tail, p)
    else filter(xs.tail, p) def modN(n: Int)(x: Int) = ((x % n) == 0) val nums = List(1, 2, 3, 4, 5, 6, 7, 8)
    println(filter(nums, modN(2)))
    println(filter(nums, modN(3)))
    }

    Note that method modN is partially applied in the two filter calls; i.e. only its first argument is actually applied. The term modN(2) yields a function of type Int => Boolean and is thus a possible candidate for the second argument of function filter.

Case Classes

    • Case classes are regular classes which export their constructor parameters and which provide a recursive decomposition mechanism via pattern matching.
    • An example for a class hierarchy which consists of an abstract super class Term and three concrete case classes Var, Fun and App.
      abstract class Term
      case class Var(name: String) extends Term
      case class Fun(arg: String, body: Term) extends Term
      case class App(f: Term, v: Term) extends Term
    • This class hierarchy can be used to represent terms of the untyped lambda calculus.
    • To facilitate the construction of case class instances, Scala does not require that the new primitive is used.
    • The main benefits of case class:
      • Dont need new when initialization;
      • better toString() method;
      • with equals() & hashCode() default;
      • with Serializable default;
      • The constructor parameters are public(can be access directly);
      • Support pattern matching;(It makes only sense to define case classes if pattern matching is used to decompose data stuctures.)
    • For better understanding of case class, u should know pattern matching first:
      • For javaer, switch is some kind of pm, but it's easy for programmer to forget 'break';
      • But in scala: [Scala has a built-in general pattern matching mechanism. It allows to match on any sort of data with a first-match policy. ]
        object PatternMatchingTest extends App {
        for (i <- 1 to 100) {
        i match {
        case 10 => println(10)
        case 50 => println(50)
        case _ =>
        }
        }
        }

Case class can be seen as a special class that have been optimized for pattern matching

      .
abstract class Person

case class Student(name: String, age: Int, studentNo: Int) extends Person
case class Teacher(name: Stirng, age: Int, teacherNo: Int) extends Person
case class Nobody(name: String) extends Person object CaseClassDemo {
def main(agrs: Array[String]): Unit = {
// case class will generate apply method, this can reduce 'new'
val p: Person = Student("john", 18, 1024) // match case
p match {
case Student(name, age, studentNo) => println(name + ":" + age + ":" + studentNo)
case Teacher(name,age,teacherNo)=>println(name+":"+age+":"+teacherNo)
case Nobody(name)=>println(name)
}
}
}

当一个类被声明为case class时,scala会帮我们做以下几件事情:

    • 自动创建伴生对象,同时在其内实现子apply方法,因为在使用时不用显式new;
    • 伴生对象内同时实现了upapply(),从而可以将case class用于模式匹配,具体之后在extractor会介绍;
    • 实现toString(), hashCode(), copy(), equals()

Extractor Objects

    • In scala, patterns can be defined independently of case classess. To this end, a method named unapply is defined to yield a so-called extractor.
    • For instance, the following code defines an extractor object `Twice`.

object Twice {
def apply(x: Int): Int = x * 2
def unapply(z: Int): Option[Int] = if (z % 2) == 0 Some(z / 2) else None
} object TwiceTest extends Application {
val x = Twice(21)
x match { case Twice(n) => Console.println(n) }
}

There are two syntactic conventions at work here:

    • The pattern case Twice(n) will cause an invocation of Twice.unapply, which is used to match even number; the return value of the unapply signals whether the argument has matched or not, and any sub-values that can be used for further matching. Here, the sub-value is z/2.
    • The apply method is not necessary for pattern matching. It is only used to mimick a constructor. val x = Twice(21) expands to val x = Twice.apply(21).
  • The return type of an unapply should be chosen as follows:
    • If it is just a test, return a Boolean.
    • If it returns a single sub-value of type T, return a Option[T].
    • If u want to return several sub-values T1, ..., Tn, group them in an optional tuple Option[(T1, ..., Tn)].
  • Extractor: 提取器是从传递给它的对象中提取出构造该对象的参数。Scala提取器是一个带有unapply方法的对象。unapply方法算是apply方法的反向操作:unapply方法接受一个对象,然后从对象中提取值,提取的值通常是用来构造该对象的值。

Scala is statically typed

  • Scala is equipped with an expressive type system that enforces statically that abstractions are used in a safe and coherent manner.
  • In particular, the type system supports:
    • generic classes
    • variance annotations
    • upper and lower type bounds
    • inner classes and abstract types as object members
    • compound types
    • explicitly typed self references
    • vies
    • polymorphic methods

Generic classes

  • Scala has built-in support for classes parameterized with types. Such generic classes are particularly useful for the development of collection classes.
  • Eg:
    class Stack[T] {
    var elems: List[T] = Nil
    def push(x: T) { elems = x :: elems }
    def top: T = elems.head
    def pop() { elems = elems.tail }
    }

    The use of type parameters allows to check that only legal elements(that of type T) are pushed onto the stack.

  • Note that subtyping of generic types is invariant. This means that if we have a stack of characters of type Stack[Char] then it cannot be used as an integer stack of type Stack[Int].

Variances

  • Scala supports variance annotations of type parameters of generic classes.

<Scala><For beginners>的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. 动态加载DataGrid表头及数据

    初始化表头 js生成前端 /*初始化表头*/ function initDataGridTitle(id) { $.ajax({ url: '/${appName}/report/***/***', ...

  2. python的索引问题

    之前自己在python索引中一直遇到这样的问题: data = np.arange(12).reshape((3,4)) print(data[:][0]) 想要索引第一列时总是索引到第一行,后来发现 ...

  3. 小程序授权demo

    <button wx:if="{{canIUse}}"   open-type="getUserInfo"  bindgetuserinfo=" ...

  4. pre打印

    echo "<pre>";print_r(var);echo "</pre>";

  5. php字符串转成数组

    /* 4.$m = “woxihuanphp”,编程实现:将字符串分割为单个字符存放到一个数组中,并打印数组? */ $m='woxihuanphp'; echo $res=trim(chunk_sp ...

  6. Linux中磁盘mbr分区——实践篇

    Linux中磁盘mbr分区——实践篇 fdisk命令 语法 fdisk(选项)(参数) 选项 -b <分区大小> 指定每个分区的大小 -l 列出分区表信息 -v 显示版本信息 参数 设备文 ...

  7. java XML(可扩展标记语言)

    XML 是EXtensible Markup Language的缩写,它是一种类似于HTML的标记语言,称为可扩展标记语言,传输数据而不是显示数据,可以自定义标签,具有自我描述性是一种通用的数据交换格 ...

  8. php导出csv

    1.导出有很多种,他有自带包的导出,但是如果你要导出7,8千的数据的话就有点困难,我最近发现一个导出可以到出1万的数据,好像只能导出csv格式的. public function down_load( ...

  9. sqlserver 优化

    避免在索引列上使用计算 where子句中,如果索引列是函数的一部分,优化器将不使用索引而使用全表扫描.例如: (低效)select ... from [dept] where [sal]*12> ...

  10. Eclipse导出WAR包

    参考: https://jingyan.baidu.com/article/ab0b56309110b4c15afa7de2.html