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包
- 和Java包管理风格相同
- 源文件中嵌套风格表示包层级关系
- 一个源文件中可以声明多个 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) //子包访问父包无需导包
}
}
}
}
访问权限
- Scala 中属性和方法的默认访问权限为 public,但 Scala 中无 public 关键字
- private 为私有权限,只在类的内部和伴生对象中可用;private[包名]增加包访问权限,包名下的其他类也可以使用
- protected 为受保护权限,Scala 中受保护权限比 Java 中更严格,同类、子类可以访问,同包无法访问
Q.E.D.