Scala学习记录

记录一下Scala与Java不同的地方。
首先Scala是一种完全面向对象的语言,一切皆对象,针对Java中不那么面向对象和设计上的缺陷作了改变。

都是方法调用

5 + 6 <=> 5.+(6)
5.toString.toFloat <=> 5 toString toFloat
for (1 <- 1 to 10) <=> for (1 <- 1.to(10))

方法参数一个时,可以省略括号
5 toString更符合人类语言

字符串格式化

printf("%s %.2f\n", "dsf", 2.782123f)
val x: Double = 12910.23423
println(s"The number is ${x}")
/* f-string变量引用后可接printf-style格式的字符串 */
println(f"The number is ${x}%07.2f")
println(raw"\\\\\")
println("The number is %010.2f".format(x))

euqals和==、eq

  • ==在Scala中,是类中定义的方法,其底层调用时,调用的是此类的equals方法,5 + 6实际上是5.+(6)
  • String的equals方法是重写过的,比较的是两个对象的具体的值。
  • eq方法比较的是两个对象的地址,其底层调用的是Java中的==比较运算符。
val str: String = new String("dsa")
val bool: Boolean = "dsa" == str
println(bool) // true

三元表达式

var b = if (10 > 9.8) 100 else 10
var ppz: Int = if (xx > 10) {
  4
} else {
  val x = 10
  val y = 7
  x + y
}

for循环

for (i <- 1 to 10) {
  println(i)
}

for (i <- 1 until 9) {
  println(i)
}

for (item <- List(1, 3, 4, 5, 6)) {

}

for (i <- 1 until 9 if i % 2 == 0) {

}

for (i <- 1 until 9 if i % 2 == 0; j = 4 - i) {
  println(f"j=${j}")
}

for (i <- 1 to 10 by 2; j <- 0 to 9 by 3){
  println(f"i=${j}, j=${i}")
}

// 列表推导式
val doubles: immutable.IndexedSeq[Double] = for (i <- 1 to 100 if i % 2 == 0) yield math.pow(i, 2).toInt
// 元组推导
val tuples: immutable.IndexedSeq[(Int, Int)] = for (i <- 1 to 100 if i % 2 == 0) yield i -> i * 2
// 转字典
println(tuples.toMap)

本质上都是Range对象的方法,to、by、until等等。

元组

val ingredient = ("Sugar", 25)
println(ingredient._1) // Sugar
println(ingredient._2) // 25

val planets =
  List(("Mercury", 57.9), ("Venus", 108.2), ("Earth", 149.6),
       ("Mars", 227.9), ("Jupiter", 778.3))
planets.foreach {
  case ("Earth", distance) =>
    println(s"Our planet is $distance million kilometers from the sun")
  case _ =>
}

val numPairs = List((2, 5), (3, -7), (20, 56))
for ((a, b) <- numPairs) {
  println(a * b)
}

case class的属性具有名称,和Python中的nameTuple类似

switch

  • 匹配常量
  • 匹配类型
    除Array外,其余反型由于类型擦除,无法匹配泛型,即List[String]识别为List
  • 对象、case class
    使用scala的提取器
  • 灵活的集合匹配
  • 对象赋值
  • 偏函数
// 简单case
import scala.util.Random

val x: Int = Random.nextInt(10)

x match {
  case 0 => "zero"
  case 1 => "one"
  case 2 => "two"
  case _ => "other"
}

//case class
```scala
sealed trait Notification

case class Email(sender: String, title: String, body: String) extends Notification

case class SMS(caller: String, message: String) extends Notification

case class VoiceRecording(contactName: String, link: String) extends Notification

def showNotification(notification: Notification): String = {
  notification match {
	case Email(sender, title, msg) =>
	  s"You got an email from $sender with title: $title $msg"
	case SMS(number, message) =>
	  s"You got an SMS from $number! Message: $message"
	case VoiceRecording(name, link) =>
	  s"You received a Voice Recording from $name! Click the link to hear it: $link"
  }
}

//仅匹配类型
sealed trait Device
case class Phone(model: String) extends Device {
  def screenOff = "Turning screen off"
}
case class Computer(model: String) extends Device {
  def screenSaverOn = "Turning screen saver on..."
}

def goIdle(device: Device): String = device match {
  case p: Phone => p.screenOff
  case c: Computer => c.screenSaverOn
}

集合

  • Scala中提供了各种可变于不可变集合,分别在scala.collection.mutable和imutable包下
  • Scala中集合提供了并行计算的方法,par,例如List(1,2,3).par.map

case class和case object

case object无参数,单例,可用于实现枚举

lazy懒加载

lazy修饰函数,懒加载效果
lazy不能修饰var类型变量

scala包

  1. 和Java包管理风格相同
  2. 源文件中嵌套风格表示包层级关系
    • 一个源文件中可以声明多个 package
    • 子包访问父包无需导包,父包访问子包需要导包
package com {

  import com.atguigu.Inner //父包访问子包需要导包

  object Outer {
    val out: String = "out"

    def main(args: Array[String]): Unit = {
      println(Inner.in)
    }
  }
  package atguigu {
    object Inner {
      val in: String = "in"

      def main(args: Array[String]): Unit = {
        println(Outer.out) //子包访问父包无需导包
      }
    }
  }

}

访问权限

  1. Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字
  2. private 为私有权限,只在类的内部和伴生对象中可用;private[包名]增加包访问权限,包名下的其他类也可以使用
  3. protected 为受保护权限,Scala 中受保护权限比 Java 中更严格,同类、子类可以访问,同包无法访问

Q.E.D.


一切很好,不缺烦恼。