使用了case
关键字的类定义就是样例类case classes
,样例类是种特殊的类。实现了类构造参数的getter方法(构造参数默认被声明为val
),当构造参数是声明为var
类型的,它将帮你实现setter
和getter
方法。
toString
, equals
, copy
和hashCode
等方法。new
,也可以不用new
结合模式匹配的代码如下:
case class Person(name :String, age : Int)
object Lesson_Caseclass {
def main(args: Array [String]) : Unit = {
val p1 = new Person("zhangsan", 10)
val p2 = Person("lisi", 20)
val p3 = Person("wangwu", 30)
val list = List(p1, p2, p3)
list.foreach{ x => {
x match {
case Person("zhangsan", 10) => println("zhangsan")
case x:Person => println("person")
case Person("lisi", 20) => println("lisi")
case _ => println("no match")
}}
}
}
}
隐式转换是在Scala
编译器进行类型匹配时,如果找不到合适的类型,那么隐式转换会让编译器在作用范围内自动推导出来合适的类型。
隐式值是指在定义参数时前面加上implicit
。隐式参数是指在定义方法时,方法中的部分参数是由implicit
修饰【必须使用柯里化的方式,将隐式参数写在后面的括号中】。隐式转换作用就是:当调用方法时,不必手动传入方法中的隐式参数,Scala
会自动在作用域范围内寻找隐式值自动传入。
implicit
关键字必须放在隐式参数定义的开头implicit
关键字修饰的参数,调用时直接创建类型不传入参数即可。object Test_Implicit {
//隐式值
implicit val address : String = "shanghai"
implicit val num: Int= 20
// 注:相同类型的隐式值只能有一个
//隐式参数
def test(implicit name: Int): Unit = {
println(name)
}
def test2(like:String): Unit= {
println(like)
}
// 部分参数为隐式参数,需使用*柯里化*的方式
def test3(name: String)(implicit age: Int) : Unit = {
println(name + ":" + age)
}
def main(args: Array [String]): Unit ={
test(name=2) // 可以附带默认值
// test
test() // 正确写法。参数是隐式参数,可以不传参数,系统会自动寻找隐式值
test2 // 错误写法。参数不是隐士参数,系统无法自动寻找隐式值,因此必须传参数
test3("joy")()
}
// 若是在不想传值,在声明隐式参数时设置默认值也可以
}
隐式转换函数是使用关键字implicit
修饰的函数。当Scala
运行时,假设如果A类型变量调用了method()
这个方法,发现A类型的变量没有method()
方法,而B类型有此method()
方法,会在作用域中寻找有没有隐式转换函数将A类型转换成B类型,如果有隐式转换函数,那么A类型就可以调用method()
这个方法。
隐式转换函数只与函数的参数类型和返回类型有关,与函数名称无关,所以作用域内不能有相同的参数类型 和返回类型 的不同名称 隐式转换函数。
class Bird(name: String) {
def fly():Unit = {
println(name + "is flying")
}
}
class Pig(xname: String) {
val name = xname
}
object Test_Implicit2 {
implicit def pigToBird(pig: Pig) : Bird = {
new Bird(pig.name)
}
/**
* 转换
* a没有b有a想要有,变成b
* 对于这样的函数而言,参数a,返回类酗A->B
*
* @param args
*/
def main(args: Array[String]) : Unit = {
val pig = new Pig("猪")
pig.fly()
}
}
使用implicit
关键字修饰的类就是隐式类。若一个变量A
没有某些方法或者某些变量时,而这个变量A
可以调用某些方法或者某些变量时,可以定义一个隐式类,隐式类中定义这些方法或者变量,隐式类中传入A
即可。
class Rabbit(s:String) {
val name = s
}
object Lesson_Implicitclass {
implicit class Animal(rabbit:Rabbit) {
val tp = "Animal"
def canFly() = {
println(rabbit.name + "can fly. . .")
}
}
def main(args: Array[String]): Unit = {
val rabbit = new Rabbit("rabbit")
rabbit.canFly()
println(rabbit.tp)
}
}
Actor Model
是用来编写并行计算或分布式系统的高层次抽象(类似java
中的Thread
)让程序员不必为多线程模式下共享锁而烦恼。Actors
将状态和行为封装在一个轻量的进程/线程中,但是不和其他Actors
分享状态,每个Actors
有自己的世界观,当需要和其他Actors
交互时,通过发送事件和消息,发送是异步的,非堵塞的(fire-andforget),发送消息后不必等另外Actors
回复,也不必暂停,每个Actors
有自己的消息队列,进来的消息按先来后到排列,这就有很好的并发策略和可伸缩性,可以建立性能很好的事件驱动系统。
ActorModel
是消息传递模型,基本特征就是消息传递Actor
之间传递时,接收消息的actor
自己决定去检查消息, actor
不是一直等待,是异步非阻塞的import scala.actors.Actor
class MyActor extends Actor {
override def act(): Unit = {
receive {
case x:String => println("String")
case _ => printLn("No!!!!!")
}
}
}
object Test_Actor {
/**
* Actor执行顺序
* 首先调用start()启动Actor
* act()方法随即被执行
* 向Actor发送消息进行处理
*
* ! 异步发送无返回值
* !! 异步发送
* !?
* @param args
*/
def main(args: Array[String]): Unit = {
val actor = new MyActor
actor ! "hello"
actor.start()
}
}
case Class Message(actor: Actor, msg: String)
class Man extends Actor {
override def act(): Unit = {
receive {
case x:String => {
printLn(x.msg)
x.actor ! "hello"
}
}
}
}
class Woman(man: Man) extends Actor {
override def act(): Unit = {
while(true) {
receive {
case x: String => println("x")
man ! Message(this, "hi")
}
}
}
}
object Test_Actor2 {
def main(args: Array[string]): Unit ={
val man = new Man
val woman = new Woman(man)
// !跟在谁后面表示这条消息是发给谁的
woman ! "hello"
man.start()
woman.start()
}
}
声明:本文是学习时记录的笔记,如有侵权请告知删除!
原视频地址:https://www.bilibili.com/video/BV1qf4y1h7rX