本文章是对过去scala学习的一些总结和查缺补漏,希望在总体上对scala有一个认识。
在函数式语言中,函数作为一等公民,可以在任何地方定义,在函数内或函数外,可以作为函数的参数和返回值,可以对函数进行组合。
Scala中提倡使用val定义变量,由于变量值是不可变的,对于值的操作并不是修改原来的值,而是修改新产生的值,原来的值保持不变。
3.scala提倡使用尾递归的方式替代递归,以避免栈溢出的情况。
4.Scala要求必须给出所有参数的类型,但是不一定给出函数返回值的类型,只要右侧的函数体中不包含递归的语句,Scala就可以自己根据右侧的表达式推断出返回类型。
scala中没有静态的概念,类似的scala提供了单例对象object
当单例对象和某个类共享名称时,单例对象被称为伴生对象(companion object);类和其伴生对象必须定义在同一个源文件里。
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。
例子来自《菜鸟教程》
(1)私有成员:private的成员仅在包含了成员定义的类或对象内部可见(java允许外部类访问其内部类的私有成员)
scala: java:
(2)保护成员:protected成员只在成员的类的子类中可以被访问(对比java,还是比java严格; java 继承或者同包可以访问)
相同包下,不是子类也不可以访问protected方法
(3) 伴生类和伴生对象可以互相访问彼此的私有成员
scala多重继承的机制是通过混入特质实现的(类的线性化,注意实现的顺序)
型变是针对Scala的泛型,允许我们在负责的类型之间建立直观的连接,而缺乏型变则会限制类抽象的重用性。
型变指像T[A] 这样的告诫类型的参数可以改变或变化的能力,型变是一种声明类型参数能如何变化以创建顺应类型的方式,如果把高阶类型T[B]赋值给T[A]不出错,就说T[A]顺应T[B]。型变的规则决定了参数化的类型的顺应性。
型变有三种形式:不变(Invariance),协变(Covariance),逆变(Contravariance)
(1)协变:协变是指把类型参数替换为其父类的能力。
类型转化要顺着方向进行,否则会报错。
(2)逆变
逆变与协变正好相反,对于任何类型T,A和B如果T[A]顺应于T[B],A >:B。
(3)总结
①方法中的参数类型声明时必须符合逆变(或不变),以让子类方法可以接收更大的范围的参数(处理能力增强);而不能声明为协变,子类方法可接收的范围是父类中参数类型的子集(处理能力减弱)。
②方法返回值声明必须符合协变或者不变。
方法可以扩展为函数,但是函数不可以转换为方法。
Scala的语法规定,将函数赋值给变量,并且在函数后面加上空格和下划线的形式成为值函数
接收其他函数作为参数的函数,也被称作高阶函数(higher-order function)
高阶函数的另外一个功能是将函数作为返回值
实现了将sayHelloFunc(也可以直接传入函数体)作为参数,将另一个参数name作为sayHelloFunc的参数传入实现sayHelloFunc(name)方法。
如果仅有的一个参数在右侧的函数体内只使用一次,则还可以将接收参数省略,并且将参数用_ 来替代
本地函数的好处是避免用private 关键字控制私有函数的访问权限
函数在变量不处于其有效作用域时,还能够对变量进行访问,即为闭包。
闭包=代码+用到的非局部变量
例子:
这样编译msg不知道是什么,所以提前定义一下局部变量。
val msg="Hello"
编译通过。
这是因为我们在值函数外面声明了一个全局变量,然后值函数中的 msg捕获到了这个全局变量, 从而使函数的定义闭合起来,这就是闭包。
指将原来接收两个参数的一个函数,转化为两个函数,第一个函数接受原来的第一个参数,返回的是用于接收第二个参数的函数。
使用尾递归的方式来代替递归,避免栈溢出。
https://blog.csdn.net/hehe_soft_engineer/article/details/103223068
包括隐式类、隐式函数、隐式值,详细介绍如下:
https://blog.csdn.net/hehe_soft_engineer/article/details/103225109
详细见下博文:
https://blog.csdn.net/hehe_soft_engineer/article/details/103334689