Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
无参数scala方法中的模式匹配_Scala - Fatal编程技术网

无参数scala方法中的模式匹配

无参数scala方法中的模式匹配,scala,Scala,我最近查阅了scala多线程教程,偶然发现了一个在Actor中实现的方法: class MyActor extends Actor def receive = { case "test" => println("received test") case _ => println("received unknown message") } } 虽然我想我知道这个方法的作用,但我不知道如何使用这样的方法(因为它不接受任何参数) 虽然这个例子是关于Akk

我最近查阅了scala多线程教程,偶然发现了一个在Actor中实现的方法:

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
    中定义,因此在实现该方法时不需要再次指定它