scala 基础知识 FAQ
问题1: 抽象成员初始化规则
① 父类先初始化
② 在初始化的过程中,如果 val 发生重写,只有最后一个重写生效。前面的会变成零值,后面的会直接继承。
参考资料:https://docs.scala-lang.org/tutorials/FAQ/initialization-order.html
示例:
abstract class A {
val x1: String
val x2: String = "mom"
println("A: " + x1 + ", " + x2)
}
class B extends A {
val x1: String = "hello"
println("B: " + x1 + ", " + x2)
}
class C extends B {
override val x2: String = "dad"
println("C: " + x1 + ", " + x2)
}
new C
输出:
A: null, null B: hello, null C: hello, dad
解析:
当一个 val 被重写时,只能初始化一次。例如,x2 在 B处初始化了,并且在 C处也初始化了,只有C处的生效。
如果 x2 同时在 B、C 两处初始化,打印的结果是
A: null, null B: hello, null C: hello, dad
如果 x2 仅在B处初始化则,打印的结果是
A: null, null B: hello, dad C: hello, dad
如果 x2不发生重写,初始值就是默认初始值。打印的结果是
A: null, mom B: hello, mom C: hello, mom
问题2: 偏函数
特性:
单参数的函数
不处理所有可能的输入,只处理那些能与至少一个 case 语句匹配的输入
可以用 isDefineAt 方法测试特定输入是否与偏函数匹配
偏函数之间可以链式连接
val pf1:PartialFunction[Any, String] = {case s:String => "YES"}
val pf2:PartialFunction[Any, String] = {case d:Double => "YES"}
val pf = pf1 orElse pf2
pf.isDefinedAt("d") // Boolean
try { pf("d").toString } catch { case _:MatchError => "ERROR!" }
问题3:隐含参数
使用可以用最后一个参数列表来推断隐含参数。隐含参数是用 implicit 关键字声明的参数。
当相应方法被调用时,我们可以显式指定这个参数,或者也可以不指定,这时编译器会在当前作用域中找到一个合适的值作为参数。
隐含参数可以代替参数默认值,而且更加灵活。
示例:
import scala.concurrent.ExecutionContext.Implicits.global
def sleep(millis: Long): Unit = {
Thread.sleep(millis)
}
// Busy work ;)
def doWork(index: Int) = {
sleep((math.random * 1000).toLong)
index
}
(1 to 5) foreach { index =>
val future = Future {
doWork(index)
}
//定义事件回调。该方法接受两个参数列表。(pf: PartialFunction[T, U])(implicit executor: ExecutionContext)
future onSuccess {
case answer: Int => println(s"Success! returned: $answer")
}
future onFailure {
case th: Throwable => println(s"FAILURE! returned: $th")
}
}
sleep(1000) // Wait long enough for the "work" to finish.
println("Finito!")
问题4:中缀表达式
中缀表达主要用于:操作符、类型声明、模式匹配
操作符
scala> val list = List() list: List[Nothing] = List() scala> "A" :: "B" :: list res4: List[String] = List(A, B)
类型声明
scala> class Foo[A,B] scala> val x: Int Foo String = null // Int Foo String 等同于 Foo[Int,String]
模式匹配
scala> case class Cons(a:String,b:String)
defined class Cons
scala> val x = Cons("one", "two")
x: Cons = Cons(one,two)
scala> x match { case "one" Cons "two" => println("ok") }
ok
// "one" Cons "two" 等同于 Cons("one", "two")
:: 在模式匹配指 case class,而不是方法
case head :: tail => …
233
浙公网安备 33010602011771号