<Scala><For beginners>
Scala Overview
Scala is object-oriented
- Scala is a pure object-oriented language in the sense that every value is an object. Types and behavior of objects are described by classes and traits. Classes are extended by subclassing and a flexible mixin-based composition mechanism as a clean replacement for multiple inheritance.
- 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
- Scala is also a functional language in the sense that every function is a value.
- Scala provides a lightweight syntax for defining anonymous functions, it supports higher-order functions, it allows functions to be nested, and supports currying.
- Scala's case classes and its built-in support for pattern matching model algebraic types used in many functional programming languages.
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>的更多相关文章
- 简单物联网:外网访问内网路由器下树莓派Flask服务器
最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...
- 利用ssh反向代理以及autossh实现从外网连接内网服务器
前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...
- 外网访问内网Docker容器
外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...
- 外网访问内网SpringBoot
外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...
- 外网访问内网Elasticsearch WEB
外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...
- 怎样从外网访问内网Rails
外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...
- 怎样从外网访问内网Memcached数据库
外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...
- 怎样从外网访问内网CouchDB数据库
外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...
- 怎样从外网访问内网DB2数据库
外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...
- 怎样从外网访问内网OpenLDAP数据库
外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...
随机推荐
- python面向对象之 类的关系
内容梗概: 1. 依赖关系 2. 关联关系, 组合关系, 聚合关系 3. 继承关系, self到底是什什么鬼? 4. 类中的特殊成员 1. 依赖关系def:在方法中给方法传递一个对象. 此时类与类之间 ...
- ActiveMQ的学习整理(代码实现PTP,以及Pub/Sub)
(一)由于在实习过程中需要用到ActiveMQ,在网上看了很多文章,现在整理出来以防忘记. (二)这篇文章比较适合之前没有接触过的同学,在看下面文章的过程中,建议先学习参考链接中的知识点,然后自己再参 ...
- 牛客练习赛32 A/B/C
https://ac.nowcoder.com/acm/contest/272/A v<=k时 答案就是k个1 否则贪心的从中间向两边添加1 #include<bits/stdc++.h ...
- 类似“未能加载文件或程序集“tesseractengine3”或它的某一个依赖项”等一些问题的解决方案
有些时候我们引用了一些32位的dll,结果就会出现类似“未能加载文件或程序集“tesseractengine3”或它的某一个依赖项”这样的问题,原因是IIS的应用程序池的设置中默认是不启用32位的应用 ...
- Charles破解网站收藏(持续更新)
1. 在这个网站(http://charles.iiilab.com/)下载破解文件 charles.jar 2. 替换掉原文件夹里的charles.jar Mac: /Applications/Ch ...
- 【转】vs IIS破除文件上传限制最全版
今天在测试一下上传文件的时候发现iis和配置存在上传文件大小限制(IIS默认大小30M,最大运行为2g:2147483647),百度了一部分资料有些发布到IIS好使,但是在VS调试中不好使.于是自己不 ...
- linux用户管理 用户和用户组管理
用户组的基本命令 groupadd [选项] [参数] -g 指定新建工作的id -r 创建系统工作组,系统工作组的ID小于500,非系统工作组大于500 -K 覆盖配置文件"/etc/lo ...
- laravel 连表查询数据库
$this->model ->select($field) ->leftJoin('b', 'b.cid', '=', 'a.id') ->orderBy("a.ad ...
- linux nginx 安装防火墙ngx_lua_waf
ngx_lua_waf是一款开源的 基于 ngx_lua的 web应用防火墙 github地址是 https://github.com/loveshell/ngx_lua_waf 安装流程如下 1 ...
- do_bootrk
1. LMB (logical memory blocks) lmb为uboot下的一种内存管理机制,用于管理镜像的内存.lmb所记录的内存信息最终会传递给kernel.在/include/lmb.h ...