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. python面向对象之 类的关系

    内容梗概: 1. 依赖关系 2. 关联关系, 组合关系, 聚合关系 3. 继承关系, self到底是什什么鬼? 4. 类中的特殊成员 1. 依赖关系def:在方法中给方法传递一个对象. 此时类与类之间 ...

  2. ActiveMQ的学习整理(代码实现PTP,以及Pub/Sub)

    (一)由于在实习过程中需要用到ActiveMQ,在网上看了很多文章,现在整理出来以防忘记. (二)这篇文章比较适合之前没有接触过的同学,在看下面文章的过程中,建议先学习参考链接中的知识点,然后自己再参 ...

  3. 牛客练习赛32 A/B/C

    https://ac.nowcoder.com/acm/contest/272/A v<=k时  答案就是k个1 否则贪心的从中间向两边添加1 #include<bits/stdc++.h ...

  4. 类似“未能加载文件或程序集“tesseractengine3”或它的某一个依赖项”等一些问题的解决方案

    有些时候我们引用了一些32位的dll,结果就会出现类似“未能加载文件或程序集“tesseractengine3”或它的某一个依赖项”这样的问题,原因是IIS的应用程序池的设置中默认是不启用32位的应用 ...

  5. Charles破解网站收藏(持续更新)

    1. 在这个网站(http://charles.iiilab.com/)下载破解文件 charles.jar 2. 替换掉原文件夹里的charles.jar Mac: /Applications/Ch ...

  6. 【转】vs IIS破除文件上传限制最全版

    今天在测试一下上传文件的时候发现iis和配置存在上传文件大小限制(IIS默认大小30M,最大运行为2g:2147483647),百度了一部分资料有些发布到IIS好使,但是在VS调试中不好使.于是自己不 ...

  7. linux用户管理 用户和用户组管理

    用户组的基本命令 groupadd [选项] [参数] -g 指定新建工作的id -r 创建系统工作组,系统工作组的ID小于500,非系统工作组大于500 -K 覆盖配置文件"/etc/lo ...

  8. laravel 连表查询数据库

    $this->model ->select($field) ->leftJoin('b', 'b.cid', '=', 'a.id') ->orderBy("a.ad ...

  9. linux nginx 安装防火墙ngx_lua_waf

    ngx_lua_waf是一款开源的 基于 ngx_lua的 web应用防火墙 github地址是  https://github.com/loveshell/ngx_lua_waf 安装流程如下 1 ...

  10. do_bootrk

    1. LMB (logical memory blocks) lmb为uboot下的一种内存管理机制,用于管理镜像的内存.lmb所记录的内存信息最终会传递给kernel.在/include/lmb.h ...