无参数scala方法中的模式匹配
我最近查阅了scala多线程教程,偶然发现了一个在Actor中实现的方法:无参数scala方法中的模式匹配,scala,Scala,我最近查阅了scala多线程教程,偶然发现了一个在Actor中实现的方法: class MyActor extends Actor def receive = { case "test" => println("received test") case _ => println("received unknown message") } } 虽然我想我知道这个方法的作用,但我不知道如何使用这样的方法(因为它不接受任何参数) 虽然这个例子是关于Akk
class MyActor extends Actor
def receive = {
case "test" => println("received test")
case _ => println("received unknown message")
}
}
虽然我想我知道这个方法的作用,但我不知道如何使用这样的方法(因为它不接受任何参数)
虽然这个例子是关于Akka的,但我认为这与Akka无关,实际上,
receive
返回部分函数。当你检查Actor
的源代码时,你会看到
type Receive = PartialFunction[Any, Unit]
因此,这意味着覆盖receive时,您提供了一个部分函数,它接受任何参数和返回单元。稍后,如果您的参与者收到消息,Akka本身将使用此分部函数对传入消息进行模式匹配
--编辑--
更具体的例子是,假设您创建了一个类似的对象
object Obj {
def receive: PartialFunction[Any, Unit] = {
case "test" => println("test case")
case 1 => println("int 1 case")
case d: Double => println("double case $d")
case _ => println("rest")
}
}
然后你可以像常规方法调用一样调用这个部分函数
scala> Obj.receive(1)
int 1 case
scala> Obj.receive("test")
test case
Actor case是特定的,只是您不直接调用receive,而是提供它,如果消息到达,Akka自己调用它
protected[akka] def aroundReceive(receive: Actor.Receive, msg: Any): Unit = receive.applyOrElse(msg, unhandled)
当然,此调用取决于许多参数,如您使用的拓扑、邮箱等。正如@Fatih Donmez所说,这是一个对等函数,它定义了特定类型的特定值、用法:
List("hello", "test").foreach {
case "test" => println("received test")
case _ => println("received unknown message")
}
(0 to 20) collect {
case i if i % 2 == 0 => i
}
(0 to 20) map {
case i if i % 2 == 0 => i * i
case j => j
}
您也可以直接使用它,如:
val f1: PartialFunction[Int, Unit] = {
case 1 => println("I am 1")
case t => println(s"I am $t")
}
f1(1)
> I am 1
f1(2)
> I am 2
orElse示例:
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i+1
}
val f = f1 orElse f2
f(1)
> 2
(0 to 10) map f
> scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4, 4, 16, 6, 36, 8, 64, 10, 100)
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
case j => j
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i * i
case j => j + 1
}
val f = f1 andThen f2
f(2)
res20: Int = 5
(0 to 10) map f
> scala.collection.immutable.IndexedSeq[Int] = Vector(1, 1, 5, 9, 17, 25, 37, 49, 65, 81, 101)
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
case j => j
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i * i
case j => j + 1
}
val f = f1 compose f2
f(2)
res18: Int = 3
(0 to 10) map f
res17: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 1, 3, 9, 5, 25, 7, 49, 9, 81, 11)
然后示例:
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i+1
}
val f = f1 orElse f2
f(1)
> 2
(0 to 10) map f
> scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4, 4, 16, 6, 36, 8, 64, 10, 100)
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
case j => j
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i * i
case j => j + 1
}
val f = f1 andThen f2
f(2)
res20: Int = 5
(0 to 10) map f
> scala.collection.immutable.IndexedSeq[Int] = Vector(1, 1, 5, 9, 17, 25, 37, 49, 65, 81, 101)
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
case j => j
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i * i
case j => j + 1
}
val f = f1 compose f2
f(2)
res18: Int = 3
(0 to 10) map f
res17: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 1, 3, 9, 5, 25, 7, 49, 9, 81, 11)
撰写示例:
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i+1
}
val f = f1 orElse f2
f(1)
> 2
(0 to 10) map f
> scala.collection.immutable.IndexedSeq[Int] = Vector(0, 2, 4, 4, 16, 6, 36, 8, 64, 10, 100)
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
case j => j
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i * i
case j => j + 1
}
val f = f1 andThen f2
f(2)
res20: Int = 5
(0 to 10) map f
> scala.collection.immutable.IndexedSeq[Int] = Vector(1, 1, 5, 9, 17, 25, 37, 49, 65, 81, 101)
val f1: PartialFunction[Int, Int] = {
case i if i % 2 == 0 => i * i
case j => j
}
val f2: PartialFunction[Int, Int] = {
case i if i % 2 != 0 => i * i
case j => j + 1
}
val f = f1 compose f2
f(2)
res18: Int = 3
(0 to 10) map f
res17: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 1, 3, 9, 5, 25, 7, 49, 9, 81, 11)
文件:
你能把文档链接也删除吗?看起来它将根据收到的消息进行模式匹配。我仍然不知道如何让这个方法做一些事情(独立于Akka)。你能提供一些关于如何调用
receive
的代码吗?我的意思是它实际上会打印一些东西?好的,现在我明白了,你可以显式地定义返回类型def receive:PartialFunction[Any,Unit]
,否则它不能在普通的标准scala中工作。在我上面的示例中,返回类型在trait-Actor
中定义,因此在实现该方法时不需要再次指定它