-
scala语言有什么特点?什么是函数式编程?有什么优点?
scala的特点:面向对象,函数式编程
函数式编程:是一种典范,将电脑的运算视作是函数的运算。
函数式编程有点:与过程化编程相比,函数式编程里的函数计算可以随时调用。 -
Scala数据类型Any和AnyRef的区别
-
Scala 中什么是闭包?
var factor = 3
val multiplier = (i:Int) => i * factor
这里我们引入一个自由变量 factor,这个变量定义在函数外面。
这样定义的函数变量 multiplier 成为一个"闭包",因为它引用到函数外面定义的变量,定义这个函数的过程是将这个自由变量捕获而构成一个封闭的函数。
- 说说Scala中隐式转换?及优缺点?
Scala提供的隐式转换和隐式参数功能,是非常有特色的功能。是Java等编程语言所没有的功能。它可以允许你手动指定,将某种类型的对象转换成其他类型的对象或者是给一个类增加方法。通过这些功能,可以实现非常强大、特殊的功能。其中所有的隐式值和隐式方法必须放到object中。
- 隐式转换函数的函数名可以是任意的,隐式转换与函数名称无关,只与函数签名(函数参数类型和返回值类型)有关
- 隐式函数可以有多个(即:隐式函数列表),但是需要保证在当前环境下,只有一个隐式函数能被识别
- 如果需要用到的一个现有类库, 但是很不幸, 里面缺少一个我们需要的方法, 这时候就可以借助隐式转换了
- 隐式转换会在编译时自动匹配, 自动为符合输入输出变量类型的函数添加对应的隐式并编译运行
//spark中的使用示例:
class PairDStreamFunctions{
def mapWithState(item : String) = println("Save " + item + " from PairDStreamFunctions")
}
class OtherDStreamFunctions{
def mapWithState(item : String) = println("Save " + item + " from OtherDStreamFunctions")
}
//定义类
class DStream[T: ClassTag]
//定义伴生对象
object DStream{
//对于所有KV类型的DStream转换为PairDStreamFunctions对象
implicit def toPairDStreamFunctions[K, V](s : DStream[(K, V)]) = new PairDStreamFunctions
//对于所有单值类型的DStream转换为OtherDStreamFunctions对象
implicit def toOtherDStreamFunctions[V](s : DStream[V]) = new OtherDStreamFunctions
}
object ImplicitDemo{
def main(args: Array[String]): Unit = {
val ds_kv = new DStream[(String, Int)]
//由于定义的DStream为KV类型
//所以会隐式转换为PairDStreamFunctions
//也就是说下面调用的是PairDStreamFunctions中的mapWithState方法
ds_kv.mapWithState("bread")
val ds = new DStream[String]
//由于定义的DStream为单值类型
//所以会隐式转换为OtherDStreamFunctions
//也就是说下面调用的是OtherDStreamFunctions中的mapWithState方法
ds.mapWithState("jam")
}
}
- 什么是函数柯里化?
柯里化(Currying)指的是把原来接受多个参数的函数变换成接受一个参数的函数过程,并且返回接受余下的参数且返回结果为一个新函数的技术。
scala柯里化风格的使用可以简化主函数的复杂度,提高主函数的自闭性,提高功能上的可扩张性、灵活性。可以编写出更加抽象,功能化和高效的函数式代码。
//闭包
def mulby(factor:Double) = (x:Double) => x * factor
var a = mulby(3)
var b = mulby(0.5)
println(a(2) + b(9))
println("==========")
//currying 柯里化
//将函数中的两个函数变为一个函数,并且把原来函数的第二个参数当做参数
def add(a:Int) = (b:Int) => a+b
var temp = add(1)(2)
println(temp)
println("==========")
//简单定义柯里化
def addnew(a:Int)(b:Int) = a+b
var cc = addnew(12)(22)
println(cc)
println("==========")
//柯里化的简单应用
def trimul(a:Int)(b:Int)(c:Int) = a * b * c
var tries = trimul(2)(4)(5)
println(tries)
-
Scala 中object是什么?有什么作用?
object 相当于 class 的单个实例,通常在里面放一些静态的 field 或者 method;
在Scala中没有静态方法和静态字段,但是可以使用object这个语法结构来达到同样的目的。
object作用:1.存放工具方法和常量 2.高效共享单个不可变的实例 3.单例模式 -
Scala 中什么是伴生类和伴生对象?有什么优点?
一个class文件,还有一个与class同名的object文件,那么就称这个object是class的伴生对象,class是object的伴生类;(注意:伴生类和伴生对象必须存放在一个.scala文件中;)
伴生类和伴生对象的最大特点是,可以相互访问; -
Scala 中的apply方法是什么?通常在哪里实现?有什么优点?
apply方法通常是在伴生对象中实现的,其目的是,通过伴生类的构造函数功能,来实现伴生对象的构造函数功能;
通常我们会在类的伴生对象中定义apply方法,当遇到类名(参数1,…参数n)时apply方法会被调用;
在创建伴生对象或伴生类的对象时,通常不会使用new class/class() 的方式,而是直接使用 class(),隐式的调用伴生对象的 apply 方法,这样会让对象创建的更加简洁; -
Scala中特质trait的用法:
首先先将trait作为接口使用,此时的trait就与Java中的接口 (interface)非常类似;
在trait中可以定义抽象方法,就像抽象类中的抽象方法一样,只要不给出方法的方法体即可;
类可以使用extends关键字继承trait,注意,这里不是 implement,而是extends ,在Scala中没有 implement 的概念,无论继承类还是trait,统一都是 extends;
类继承后,必须实现其中的抽象方法,实现时,不需要使用 override 关键字;
Scala不支持对类进行多继承,但是支持多重继承 trait,使用 with 关键字即可。
trait中未被实现的方法默认是抽象方法,因此不需要在方法前加abstract -
说说Scala中的协变、逆变、非变:
-
scala中高阶函数是什么?有哪些?
Scala混合了面向对象和函数式的特性,我们通常将可以作为参数传递到方法中的表达式叫做函数。在函数式编程语言中,函数是“头等公民”,把函数最为参数或者是返回值是函数的函数叫高阶函数
高阶函数包含:作为值的函数、匿名函数、闭包、柯里化等等。 -
Scala中特质的调用链:
Scala中支持让类继承多个trait后,可依次调用多个trait中的同一个方法,只要让多个trait中的同一个方法,在最后都依次执行 super 关键字即可;
类中调用多个trait中都有的这个方法时,首先会从最右边的trait的方法开始执行,然后依次往左执行,形成一个调用链条;
这种特性非常强大,其实就是设计模式中责任链模式的一种具体实现; -
Scala中的模式匹配和样例类、option类型:
Scala有一个十分强大的模式匹配机制,可以应用到很多场合:如switch语句、类型检查等。
Scala还提供了样例类,对模式匹配进行了优化,可以快速进行匹配。用case class定义。
在Scala中Option类型用样例类来表示可能存在或者可能不存在的值(Option的子类有Some和None)。Some包装了某个值,None表示没有值
参考:https://blog.csdn.net/CSDN_bird/article/details/100687097