Scala总结

本文章是对过去scala学习的一些总结和查缺补漏,希望在总体上对scala有一个认识。

一、scala函数式编程特性

1.简介

在函数式语言中,函数作为一等公民,可以在任何地方定义,在函数内或函数外,可以作为函数的参数和返回值,可以对函数进行组合。

2.不变性

Scala中提倡使用val定义变量,由于变量值是不可变的,对于值的操作并不是修改原来的值,而是修改新产生的值,原来的值保持不变。

3.scala提倡使用尾递归的方式替代递归,以避免栈溢出的情况。

4.Scala要求必须给出所有参数的类型,但是不一定给出函数返回值的类型,只要右侧的函数体中不包含递归的语句,Scala就可以自己根据右侧的表达式推断出返回类型。

二、单例对象

1.简介

scala中没有静态的概念,类似的scala提供了单例对象object

当单例对象和某个类共享名称时,单例对象被称为伴生对象(companion object);类和其伴生对象必须定义在同一个源文件里。

2.Apply方法

Scala 中常常通过伴生对象的Apply 方法构建对象,通常apply 方法返回的是伴生类的对象

Scala 通过类和同名的“伴生”对象来达到实例方法和静态方法并存的类

三、模式匹配

1.模式匹配是检查某个值(value)是否匹配某一个模式的机制,一个成功的匹配同时会将匹配值解构为其组成部分 。它是Java中的switch语句的升级版,同样可以用于替代一系列的 if/else 语句。

2.模式(pattern),这里所的模式并不是设计模式里的模式,而是数据结构上的,这个模式用于描述一个结构的组成。这个pattern 和正则表达式的模式有点像,主要针对的是不同类型的数据结构,正则表达式只针对字符串(比如正则表达式里 “^A.*” 这个pattern 表示以A开头,后续一个或多个字符组成的字符串);在我们模式匹配 中,List(“A”, _, _*) 也是个pattern,表示第一个元素是”A”,后续一个或多个元素的List。

3. 模式可以当作对某个类型,其内部数据在结构上抽象出来的表达式。如上面的List(“A”, _, _*)就是一种List 结构的pattern。模式匹配(pattern-matching)则是匹配变量是否符合这种pattern。

Scala总结_第1张图片

例子来自《菜鸟教程》

四、面向对象

1.访问权限控制(对比java)

(1)私有成员:private的成员仅在包含了成员定义的类或对象内部可见(java允许外部类访问其内部类的私有成员)

scala:                                                                           java:

Scala总结_第2张图片Scala总结_第3张图片

(2)保护成员:protected成员只在成员的类的子类中可以被访问(对比java,还是比java严格; java 继承或者同包可以访问)

相同包下,不是子类也不可以访问protected方法

Scala总结_第4张图片

(3) 伴生类和伴生对象可以互相访问彼此的私有成员

2.scala多重继承的机制

scala多重继承的机制是通过混入特质实现的(类的线性化,注意实现的顺序)

3.scala型变

型变是针对Scala的泛型,允许我们在负责的类型之间建立直观的连接,而缺乏型变则会限制类抽象的重用性。

型变指像T[A] 这样的告诫类型的参数可以改变或变化的能力,型变是一种声明类型参数能如何变化以创建顺应类型的方式,如果把高阶类型T[B]赋值给T[A]不出错,就说T[A]顺应T[B]。型变的规则决定了参数化的类型的顺应性。

型变有三种形式:不变(Invariance),协变(Covariance),逆变(Contravariance)

(1)协变:协变是指把类型参数替换为其父类的能力。

Scala总结_第5张图片

类型转化要顺着方向进行,否则会报错。

(2)逆变

逆变与协变正好相反,对于任何类型T,A和B如果T[A]顺应于T[B],A >:B。

Scala总结_第6张图片

(3)总结

①方法中的参数类型声明时必须符合逆变(或不变),以让子类方法可以接收更大的范围的参数(处理能力增强);而不能声明为协变,子类方法可接收的范围是父类中参数类型的子集(处理能力减弱)。

②方法返回值声明必须符合协变或者不变。

Scala总结_第7张图片

五、函数

1.函数和方法的对比:

方法可以扩展为函数,但是函数不可以转换为方法。

2.值函数

Scala的语法规定,将函数赋值给变量,并且在函数后面加上空格和下划线的形式成为值函数

Scala总结_第8张图片

3.高阶函数

接收其他函数作为参数的函数,也被称作高阶函数(higher-order function)

高阶函数的另外一个功能是将函数作为返回值

Scala总结_第9张图片

实现了将sayHelloFunc(也可以直接传入函数体)作为参数,将另一个参数name作为sayHelloFunc的参数传入实现sayHelloFunc(name)方法。

如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,并且将参数用_ 来替代

Scala总结_第10张图片

4.本地函数

本地函数的好处是避免用private 关键字控制私有函数的访问权限

5.闭包

函数在变量不处于其有效作用域时,还能够对变量进行访问,即为闭包。

闭包=代码+用到的非局部变量

例子:

Scala总结_第11张图片

这样编译msg不知道是什么,所以提前定义一下局部变量。

val msg="Hello"

Scala总结_第12张图片

编译通过。

这是因为我们在值函数外面声明了一个全局变量,然后值函数中的 msg捕获到了这个全局变量, 从而使函数的定义闭合起来,这就是闭包。

6.柯里化Curring

指将原来接收两个参数的一个函数,转化为两个函数,第一个函数接受原来的第一个参数,返回的是用于接收第二个参数的函数。

Scala总结_第13张图片

7.(尾)递归

使用尾递归的方式来代替递归,避免栈溢出。

https://blog.csdn.net/hehe_soft_engineer/article/details/103223068

8.隐式转换

包括隐式类、隐式函数、隐式值,详细介绍如下:

https://blog.csdn.net/hehe_soft_engineer/article/details/103225109

六、scala集合

详细见下博文:

https://blog.csdn.net/hehe_soft_engineer/article/details/103334689

你可能感兴趣的:(Scala)