参考链接
Scala和Java 的比较
- scala语言和Java语言很相似
- Scala语言比Java语言使用更加简单
- Scala语言有自己专有的库,同时在编程过程中可以直接使用Java的Api
- Scala支持Maven,Gradel等Java构建工具
Scala语言的Hello World
编写HelloWorld.scala文件
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello, World!")
}
}
编译命令
scalac HelloWorld.scala
执行命令
scala -classpath . HelloWorld
Scala语言:一切皆是对象
Scala:函数式编程
将函数作为方法的参数传递给另外一个函数的参数
object Timer {
def oncePerSecond(callback: () => Unit): Unit = {
while (true) { callback(); Thread.sleep(1000) }
}
def timeFlies(): Unit = {
println("time flies like an arrow...")
}
def main(args: Array[String]): Unit = {
oncePerSecond(timeFlies)
}
}
- oncePerSecond函数的参数callback是一个函数调用
- ()=>Unit表示该函数参数的返回值为空,且不接受其他参数
- timeFiles函数为传递给oncePerSecond的参数
- main为主函数
程序运行的结果:每隔1秒打印一句“time flies like an arrow…”
匿名函数:和Java中Lambda表达式相似
省略函数的名称,直接在传递函数时书写函数体
object TimerAnonymous {
def oncePerSecond(callback: () => Unit): Unit = {
while (true) { callback(); Thread.sleep(1000) }
}
def main(args: Array[String]): Unit = {
oncePerSecond(() =>
println("time flies like an arrow..."))
}
}
模式匹配
场景
自定义实现一个简单的加法运算,允许包含未知参数,例如x。但是在实际计算时,可以由用户显式的指定x的值。
加法运算和二叉树之间的对应关系:
- 分支结点可以看成是操作符
- 叶节点看成是具体的阿拉伯数字
- 这样采用一定的二叉树遍历策略,就可以计算出对应的值
实现
- 编写Tree类
abstract class Tree
object Tree {
case class Sum(l: Tree, r: Tree) extends Tree
case class Var(n: String) extends Tree
case class Const(v: Int) extends Tree
}
类Tree为抽象类
自定义实现Tree的几个子类,其中Sum子类表示分支结点;Const子类表示叶节点
- 进行模式匹配
(1)所谓的模式匹配也就是实现一个函数,其中函数的参数的类型不确定,但是可以在方法体内,通过case语句进行动态的判断,根据不同的类型选择不同的操作
(2)模式匹配在形式上和函数很相像
object test {
// 定义运行时环境,将x替换成5,将y替换成7
type Environment = String => Int
val env: Environment = { case "x" => 5 case "y" => 7 }
// 进行模式匹配
/*
1. 进行匹配的对象为t
2. 如果t为Sum类型(注意带上Sum的两个参数,在类定义时确定),则递归对l和r进行处理
3. 如果t为变量类型,根据运行时环境进行解析
4. 如果t为阿拉伯数字,则直接返回该数字
*/
def eval(t: Tree, ev: Environment): Int = t match {
case Sum(l, r) => eval(l, ev) + eval(r, ev)
case Var(n) => ev(n)
case Const(v) => v
}
def main(args: Array[String]): Unit = {
//write a simple main function which performs several operations on the expression (x+x)+(7+y)
val exp: Tree = Sum(Sum(Var("x"),Var("x")),Sum(Const(7),Var("y")))
println("Expression: " + exp)
println("Evaluation with x=5, y=7: " + eval(exp, env))
}
- 程序执行结果
接口:Trait
- 定义接口:实现日期的比较
//相当于Java中的接口
trait Ord {
def < (that: Any): Boolean
def <=(that: Any): Boolean = (this < that) || (this == that)
def > (that: Any): Boolean = !(this <= that)
def >=(that: Any): Boolean = !(this < that)
}
值得注意的是,接口中声明的方法在本接口中可以直接调用,在上面接口中< 没有方法体,需要子类实现,<=方法是基于<方法实现的
- 实现接口
//创建Date日期类
class Date(y: Int, m: Int, d: Int) extends Ord {
def year = y
def month = m
def day = d
//重写toString方法
override def toString(): String = s"$year-$month-$day"
// 重写equals方法,使用到了模式匹配
override def equals(that: Any): Boolean = that match {
case d: Date => d.day == day && d.month == month && d.year == year
//其他情况报错
case _ => false
}
//实现接口中定义的< 方法
def <(that: Any): Boolean = that match {
case d: Date =>
(year < d.year) ||
(year == d.year && (month < d.month ||
(month == d.month && day < d.day)))
//其他情况报错
case _ => sys.error("cannot compare " + that + " and a Date")
}
}
- 测试类
object test {
def main(args: Array[String]): Unit = {
val date1 = new Date(2023, 1, 23)
val date2 = new Date(2023, 1, 21)
println(date1.<(date2))
println(date2.>(date1))
}
}
使用泛型
和Java很类似
- 创建泛型类
class Reference[T] {
private var contents: T = _
def set(value: T): Unit = { contents = value }
def get: T = contents
}
- 测试
object test {
def main(args: Array[String]): Unit = {
val cell = new Reference[Int]
cell.set(13)
println("Reference contains the half of " + (cell.get * 2))
}
}
语法说明
在上面都没有强掉具体的语法,实际上想必大家已经看出来了,在Scala中,一切都是对象,因此无论是变量,还是函数,还是类在语法格式上相似度很高
- 变量的定义
val env: Environment =
val <标识符> : 变量的类型 =
- 函数的定义
def eval(t: Tree, ev: Environment): Int = {}
def <函数名称>([<参数名称> : <参数类型>]) : <返回值类型> ={}
- 模式匹配的定义
def eval(t: Tree, ev: Environment): Int = t match {
case Sum(l, r) => eval(l, ev) + eval(r, ev)
}
- 子类定义
abstract class Tree
object Tree {
case class Sum(l: Tree, r: Tree) extends Tree
case class <子类名称>([参数列表]) extends <父类名称>
}
- main函数
object test {
def main(args: Array[String]): Unit = {
println("hello world")
}
}