YMLiang

Scala语言的特点:

  • 基于JVM(可以重用类库)
  • 简洁优雅
  • 面向对象 + 函数式编程(FP)

函数式编程的数学基础是 : λ演算
函数式编程中,所有的数据都是不可变的,不同的函数之间通过数据流来交换信息,函数作为FP中的一等公民,享有跟数据一样的地位,可以作为参数传递给下一个函数,同时也可以作为返回值。

基础语法

Scala基础

  • 程序文件的名称可以不与对象名称完全匹配;
  • 程序从main()方法开始,main 方法应该在object中
  • $字符是Scala中的保留关键字;
  • 语句在单行上分号可省略;
  • 操作符是方法,没有提供 ++、–操作符;
  • 使用val声明不可变的值,使用var声明可变的变量;鼓励使用val,避免使用var;
  • 需要给出值或者变量的类型,scala可以做自动类型推断。必要时可以指定类型;
  • 拥有和java一样的数据类型,和java的数据类型的内存布局、精度完全一致;

控制结构和函数

  • if 语句有返回值;
  • 基础类型都继承自AnyVal,应用类型都继承自AnyRef,AnyVal 与 AnyRef 继承自Any;
  • 块语句是一个包含于{}中的语句序列,块中最后一个表达式的值就是块的值
  • 字符串插值器:s、raw、f;
  • for循环中:to、until;很方便的写多重循环;
    for (i <-1 to 3; j<-1 to 3[;] if i != j) print((10*i+j) + “ “ )
  • for循环中的守卫语句(guard 语句);for推导式(yield);
  • Range对象:1 to 100 by 2; Range(1, 100, 2); (1 to 100).toArray;
  • 只要函数不是递归的,不需要指定返回类型。Scala可以进行自动类型推断;函数的定义:
    def funcname(x: Int, y: Int): Int = {
    x + y
    
    }
  • 默认参数、带名参数、变长参数;
  • 懒值。当val被声明为lazy,它的初始化将被推迟,直到首次对它取值(只有val才能定义为lazy)

数组(Array)

Array:长度固定、元素可变、可索引、存放相同类型的集合
ArryBuffer:长度可以变;要导包;打印方便
toArray / toBuffer
增加元素:+=、:+、+:
减元素:-=
增加一个数组: ++= ++

map、foreach、reduce、flatMap
max、min、sorted、reverse
sum、product、size、length、indices
count、filter(Not)、distinct、take、takeRigth、takeWhile
drop、dropRigth、dropWhile
zip、unzip、head、tail、last、init
union、groupBy、contains

Map

存放键值对的容器(集合);
默认使用不可变的Map,这里的不可变是指值不可变;如果要给Map增加值应声明为var;
如果要使用可变的Map,要显示声明;import scala.collection.mutable.Map
getOrElse

Tuple

可以存放不同类型的元素,元组是不可变的;最大的长度22;
访问使用x._1、x._2

面向对象

大处使用面向对象;
小处使用函数式编程;(操作数据)

用class声明类,用object声明单例对象;
用final阻止一个对象被继承;
用abstract阻止对象被实例化;
用this指代对象本身;
缺省的访问限定符为public;

类 & 对象

定义类的成员变量访问属性:
class Student(var name: String, var age)
class Student(val name: String, val age)
class Student(private val name: String, val age)【示意】
class Student(private[this] val name: String, val age)【示意】
自定义getter、setter方法;
定义java风格的getter、setter方法;

主构造函数:就是类体本身

辅助构造函数:命名为this,跟不同的参数列表;第一行必须调用主构造器 或 其他辅助构造器;

用来定义常量和工具方法;
实现单例类;
与java中的static 类与方法类似;
没有参数列表;其他的性质与class类似;

程序的入口点,main方法定义在其中
apply方法也放在这里;

继承 & 特质

scala采用object关键字实现单例对象,具备和Java静态方法同样的功能;
object本质上可以拥有类的所有特性,除了不能提供构造器参数;
对于任何在Java中用单例对象的地方,在scala中都可以用object实现:

  • 作为存放工具函数或常量的地方
  • 高效地共享单个不可变实例

当单例对象与某个类具有相同的名称时,它被称为这个类的“伴生对象”,类称为伴生类;
类和它的伴生对象必须存在于同一个文件中,而且可以相互访问私有成员(字段和方法);
object的apply、unapply、update方法
定义伴生对象中的apply方法,主要用来解决简化对象的初始;

trait(接口),是scala代码重用的基本单元,可以同时拥有抽象方法和具体方法;

函数式编程

case class & case object

样例类是scala中特殊的类。当声明样例类时,如下事情会自动发生:

  • 构造器中每一个参数都成为val(不建议使用var);
  • 提供apply方法;
  • 提供unapply方法;
  • 将生成toString、equals、hashCode和copy方法;
  • 继承了Product和Serializable;

case class和其他类型完全一样,可以添加方法和字段,可以继承;
case class最大的用处是用于模式匹配;

case class是多例的(后面要跟构造参数),case object是单例的

模式匹配

模式匹配使用 match… { case … }的语法结构,具有以下特点:

  • match 语句有返回值;
  • case分支语句不会贯穿到下一个case语句;
  • 如果没有任何一个模式匹配上,会抛出异常(MatchError);
  • 通常最后一个语句与 _ 匹配;

模式匹配无处不在;

## Option类型 ##
Option是Scala编程中常用的一个类,用来避免指针异常;
包含两个实例:Some、None;
Option类型提供了getOrElse方法;
可将Option[T]看做是一个集合,这个集合只要么

  • 只包含一个元素(被包装在Some中);
  • 要么就不存在元素(返回None);

函数

函数字面量:函数的值;(x, str) => { x + str.length }
函数的类型:(Int, String) => Int
匿名函数:即Lambda表达式,没有名称的函数;

可使用下划线作为一个或多个参数的占位符,只要每个参数在函数字面量内仅出现一次。
多个下划线指代多个参数;

高阶函数:接收一个或多个函数作为输入 或 输出一个函数。
闭包是一种特殊函数,是在其上下文中引用了自由变量的函数;(闭包反映了一个从开放到封闭的过程)
柯里化:将原来接收两个参数的函数变成新的接收一个参数的函数的过程;
部分应用函数(偏应用函数):是指缺少部分(甚至全部)参数的函数;
偏函数:只接受部分输入参数的函数;

在偏函数中只能使用 case 语句,整个函数必须用大括号包围;通常使用偏函数进行类型转换,拆解;

集合

Seq(序列)、Set(集)、map(映射)
集合的分类:有序、无序;可变、不可变;
默认提供不可变版本,使用可变版本需要显示声明;

Seq

Seq:具有一定长度的可迭代访问的对象,每个元素均带有一个从0开始计数的固定索引位置。
常见的Seq类型包括:List、Vector、String、Range、Queue、Stack;
List : 列表是不可变的(元素不能通过赋值改变);结构是递归的;
List递归的表示 :head :: tial
常用操作符 :Nil、::、:::(++)
Vector是以树形结构的形式实现,每个节点可以有不超过32个子节点。(4层可存放100W个节点);
Range通常表示一个整数序列;

set

与数学集合的概念较为类似。元素没有重复值,不保证元素的存放顺序;

高阶函数

flatMap、flatten、reduce
fold、foldLeft、foldRight
aggregate

隐式转换

隐式转换可以为现有的类库添加功能; 隐式转隐为隐藏了相应的细节;
隐式函数是指那种以implicit关键字声明的带有单个参数的函数;

隐式转换规则:
1、源 或 目标类型 的伴生对象中的隐式函数
2、当前作用域的隐式函数

隐式参数有点类似缺省参数,如果在调用方法时没有提供某个参数,编译器会在当前作用域查找是否有符合条件的 implicit 对象可以作为参数传入;

Ordered、Ordering

Ordered 提供比较器模板,可以自定义多种比较方式(我们常用它来解决对象的排序问题)
Ordering 定义了相同类型间的比较方式【Ordering.Int、Ordering.String.reverse】

sorted、sortWith、sortBy

函数式编程的特点

不变性
函数式一等公民
递归和尾递归

函数式编程相关的技术

少用循环和遍历,多使用 map 、 reduce等函数;
柯里化(currying);
高阶函数(higher order function);
递归(recursing)和尾递归
管道(pipeline)

函数 与 方法

使用 def 定义的是方法;使用 val 定义的是函数;
二者在大多数情况下可以认为是相等的;

方法是类的组成部分,不能单独存在;
函数是一个完整的对象,可以独立存在;
方法可以转化为函数;

下划线的用法:
导包
类成员变量赋值
可变参数
类型通配符
模式匹配
Tuple访问
简化函数字面量
定义setter方法
部分应用函数
方法转换为函数

+:、:+、++、::、:::

type:声明类型,提供可读性

 评论


博客内容遵循 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 协议

本站使用 Material X 作为主题 , 总访问量为 次 。
Copyright 2018-2019 YMLiang'BLOG   |   京ICP备 - 19039949  |  载入天数...载入时分秒...