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. 赵炯博士《Linux内核完全注释》

    赵炯:男,1963年10月5日出生,江苏苏州人,汉族. 同济大学机械工程学院机械电子教研室副教授,从事教学和科研工作. 现在主要为硕士和博士研究生开设<计算机通信技术>.<计算机控制 ...

  2. 邂逅明下 HDU - 2897

    Problem description: 有三个数字n,p,q,表示一堆硬币一共有n枚,从这个硬币堆里取硬币,一次最少取p枚,最多q枚,如果剩下少于p枚就要一次取完.两人轮流取,直到堆里的硬币取完,最 ...

  3. 4.1.3 Euclid's Game (POJ 2348)

    Problem description: 以辗转相除法为基础,给定两个整数a和b,Stan和Ollie轮流从较大的数字中减去较小数字的倍数(整倍数),并且相减后的结果不能为零.Stan先手,在自己的回 ...

  4. 《剑指offer》总结一

    目录 1.二维数组中的查找(223ms) 2.替换空格(24ms) 3.从尾到头打印链表(22ms) 4.重建二叉树(37ms) 5.用两个栈实现队列 1.二维数组中的查找(223ms) 题目描述: ...

  5. 文件名简体转繁体bat

    @echo off rem 指定文件夹路径 set "fd=D:\下载的图片" rem 0为转换文件名,1为转换文件夹名,2为同时转换文件名和文件夹名 set f=0 rem 0为 ...

  6. 【IDEA】【5】快捷键

    前言: 1,更改快捷键:File->Settings->Keymap 2,我自定义的快捷键 shitf+alt+s getter,setter,toString方法 (修改处:Keymap ...

  7. vue3.0 配置公共请求地址

    正常请求接口: return request({ url: 'http://192.168.1.0/User/cancelUpgrade', method: 'get', params: data } ...

  8. Connection parameters are correct , SSL not enabled

    这个仅仅是个消息提示,告诉你SSL not enabled.无须理会,直接点击ok

  9. weblogic隐藏版本号教程(10.3.6为例)

    隐藏版本号,如同大多数中间件都是取消Server头的发送:weblogic而言其默认就是不发送Server头的(即下边的“发送服务器标头”默认就是没钩选的). 写此教程的原因,一是以防Server头被 ...

  10. Qt画笔实现波形区域图

    参考文章:https://blog.csdn.net/yuxing55555/article/details/79752978 效果图: void WareArea::paintEvent(QPain ...