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

posted on 2019-11-16 22:27  Lemo_wd  阅读(176)  评论(0编辑  收藏  举报

导航